YbtOJ 递推算法课堂过关 例2 奇怪汉诺塔【递推(简单DP)】

在这里插入图片描述


思路

此题是四个塔,所以
首先我们要知道三塔的递推。
d [ i ] d[i] d[i] 表示从A塔移动 i i i 个圆盘到C塔的最优步数,
考虑先移动 i − 1 i-1 i1 个圆盘到B塔,则最优步数为 d [ i − 1 ] d[i-1] d[i1],此时A塔还剩 1 1 1 个圆盘。
再将那 1 1 1 个圆盘移动到C塔,最后把 j − 1 j-1 j1 个圆盘移动到C塔,
最后把方案数累加: d [ i ] = d [ i − 1 ] + 1 + d [ i − 1 ] d[i]=d[i-1]+1+d[i-1] d[i]=d[i1]+1+d[i1]

在回到四塔问题,因为多了一个塔,所以要设一个 j j j 来枚举移动的盘数以求得最优解。
有三塔的铺垫,四塔我就不再讲解太细。
首先我们设 f [ i ] f[i] f[i] 表示从A塔移动 i i i 个圆盘到D塔的最优步数,
先移动 j j j 个圆盘到B塔,再把 i − j i-j ij 个圆盘移动到D塔,此时B塔圆盘比D塔的都要小,所以直接移动j个圆盘到D塔。
请注意区分什么时候用 d [    ] d[~~] d[  ],什么时候用 f [    ] f[~~] f[  ]
最终公式为: f [ i ] = min ⁡ ( f [ i ] , f [ j ] + f [ j ] + d [ i − j ] ) f[i]=\min(f[i],f[j]+f[j]+d[i-j]) f[i]=min(f[i],f[j]+f[j]+d[ij]) min ⁡ \min min 是因为枚举了 j j j 取最小。

C o d e Code Code

#include<iostream>
#include<cstdio>
using namespace std;
long long n,d[100],f[100];
int main()
{
    
    
	while(n!=12)
	 {
    
    
	    n++; 
		for(int i=1; i<=n; i++) 
		   d[i]=2*d[i-1]+1;
		f[1]=1;
		for(int i=2; i<=n; i++)
		 {
    
    
		 	f[i]=123456789;
		 	for(int j=1; j<i; j++)
		 	   f[i]=min(f[i],2*f[j]+d[i-j]);
		 }
		cout<<f[n]<<endl;
	 }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/111634109