思路
此题是四个塔,所以
首先我们要知道三塔的递推。
设 d [ i ] d[i] d[i] 表示从A塔移动 i i i 个圆盘到C塔的最优步数,
考虑先移动 i − 1 i-1 i−1 个圆盘到B塔,则最优步数为 d [ i − 1 ] d[i-1] d[i−1],此时A塔还剩 1 1 1 个圆盘。
再将那 1 1 1 个圆盘移动到C塔,最后把 j − 1 j-1 j−1 个圆盘移动到C塔,
最后把方案数累加: d [ i ] = d [ i − 1 ] + 1 + d [ i − 1 ] d[i]=d[i-1]+1+d[i-1] d[i]=d[i−1]+1+d[i−1]
在回到四塔问题,因为多了一个塔,所以要设一个 j j j 来枚举移动的盘数以求得最优解。
有三塔的铺垫,四塔我就不再讲解太细。
首先我们设 f [ i ] f[i] f[i] 表示从A塔移动 i i i 个圆盘到D塔的最优步数,
先移动 j j j 个圆盘到B塔,再把 i − j i-j i−j 个圆盘移动到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[i−j]) 取 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;
}