1 条题解

  • 0
    @ 2025-5-4 14:01:25

    首先回顾一下经典汉诺塔,我们设f[i]表示放好i个盘的最少步数。 先思考有两个盘子,我们把1盘放到B柱,然后把2盘放到C柱,最后把1盘放到C柱。 那么三个盘子就是先执行一遍同样的操作,发现B柱空了。干脆把B柱当作C柱,那么直接把3盘移到B柱上。 发现了什么?又变成了两个盘子的情况?! 以此类推,i个盘子其实是把执行一次i-1时的步骤,把i盘放到空柱上,最后把剩下i-1个盘子放到i盘所在的柱上。 那么递推式显而易见f[i]=f[i-1]+1+f[i-1]=2f[i-1]+1。 思考有4根柱子,我们设ff[i]表示放好i个盘的最少步数。 一样思考,我们假设已经放了j(j<i)个盘子到k柱,这时,剩下的是啥? So easy!i-j个盘子和3个柱子。。。?! 然后呢?j个盘子和4个柱子 那么递推式又双显而易见ff[i]=min{ff[j]+f[i-j]+ff[j]}=min{2ff[j]+f[i-j]}(1<=j<i) 初始化(可以不写):f[1]=1;ff[1]=1; 结束了,我用的f[0][i]代替f[i],用f[1][i]代替ff[i]。

    原文链接:https://blog.csdn.net/YIERsRP/article/details/81318428

    
    #include<bits/stdc++.h>
     
    using namespace std;
     
    int f[5][25],n=12;
     
    int main()
    {
    	for(int i=1;i<=n;i++)
    	  f[0][i]=0,f[1][i]=2147364847;
    	f[0][1]=1;f[1][1]=1;
    	for(int i=1;i<=n;i++)
    	  f[0][i]=2*f[0][i-1]+1;
    	for(int i=2;i<=n;i++)
    	  for(int j=1;j<i;j++)
    	    f[1][i]=min(f[1][i],2*f[1][j]+f[0][i-j]);
    	for(int i=1;i<=n;i++)
    	  printf("%d\n",f[1][i]);
    	return 0;
    } 
    
    
    
    • 1

    信息

    ID
    959
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者