zoukankan      html  css  js  c++  java
  • UVa10795

    题目链接

    简介:新汉诺塔问题(给出了初始状态和目标状态)

    分析:
    我们考虑最大的盘子,如果这个盘子初始状态和中止状态在一个柱子上,说明我们根本不用移动ta
    那么我们找到编号最大的需要移动是盘子k(初始状态所在的柱子和终止状态不一样)
    假设k要从x—>y,那么在移动k之前三根柱子的状态一定是(我们可以忽略那些编号大于k且不需要移动的柱子):
    x:k
    y:空
    z:1~k-1有序摆放
    我们称这种状态为中间状态

    由于盘子的移动是可逆的,根据对称性,
    问题所需要的步数就是:(初始状态到达中间状态的步数)+(终止状态到达中间状态的步数)+1

    汉诺塔问题有一个经典结论,不得不提一下:

    把n个有序的盘子由一根柱子全部移动到另一根柱子上,所需的步数是:2^n-1

    这就是一个递归的过程,
    递归的柿子就可以表示为:f(start,i,final)=f(start,i-1,6-final-start[i])+f(finish,i-1,6-final-start[i])+1
    start表示初始状态,finish表示终止状态,final表示需要移动到的柱子
    我们把柱子依次编号1,2,3,那么除了初始状态和终止状态,剩下的那根柱子的编号就是6-final-finish[i]

    f(P,now,final)表示当前的状态是P,我们需要把1~now个盘子全都移动到final上

    怎么计算f(P,now,final)
    如果当前的盘子now已经在目标柱子final上了,那f(P,now,final)=f(P,now-1,final)
    如果不在目标柱子上,我们就要分成三步:

    • 把now-1个盘子移动到(6-final-P[now])
    • 把第now个盘子移动到final,需要一步
    • 把now-1个盘子从(6-final-P[now])移动到final,注意这里是把now-1个盘子全部按顺序移动到final
      根据汉诺塔问题的经典结论,这需要(2^(now-1)-1)

    所以f(P,now,final)=f(P,now-1,6-final-P[now])+2^(now-1)

    //这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define ll long long
    
    using namespace std;
    
    int n;
    int start[103],finish[103];
    
    ll f(int *P,int now,int final)
    {
        if (!now) return 0;
        if (P[now]==final)
           return f(P,now-1,final);
        return f(P,now-1,6-final-P[now])+(1LL << (now-1));
    }
    
    int main()
    {
        int cnt=0;
        while (scanf("%d",&n)!=EOF&&n)
        {
            for (int i=1;i<=n;i++) scanf("%d",&start[i]);
            for (int i=1;i<=n;i++) scanf("%d",&finish[i]);
    
            int i=n;
            while (i>=1&&finish[i]==start[i]) i--;
    
            ll ans=0;
            if (i>=1)
            {   
                int t=6-start[i]-finish[i];
                ans=f(start,i-1,t)+f(finish,i-1,t)+1;
            }
    
            printf("Case %d: %lld
    ",++cnt,ans);
        }
        return 0;
    }
  • 相关阅读:
    编译错误error:&nbsp;invalid&amp;nbsp…
    移植OK6410&#039;S&nbsp;dm9000ae…
    JavaScript 正则表达式-严格匹配
    JavaScript indexOf() 方法
    JavaScript splice() 方法
    Css文字效果
    知识点-语句
    知识点—变量、运算符(表达式)
    WPF RichTextBox相关总结
    WPF调用图片路径,或资源图片
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673021.html
Copyright © 2011-2022 走看看