题目大意
要你求有 1~12 个圆盘时的四塔汉诺塔。
每行一个答案。
解
设 d [ i ] d[i] d[i] 为三塔情况下将i个圆盘全部移动至目标塔的最小次数。
易得,应将 i − 1 i-1 i−1 个圆盘先移动至 B B B,再将最大的圆盘移动到 C C C ,最后将 i − 1 i-1 i−1 个圆盘移动到 C C C 上。
所以: d [ i ] = d [ i − 1 ] ∗ 2 + 1 d[i] = d[i-1] * 2 + 1 d[i]=d[i−1]∗2+1
设 f [ i ] f[i] f[i] 为四塔情况下将i个圆盘全部移动至目标塔的最小次数。
先将 j j j 个盘子在四塔情况下移动至 B B B,然后将剩下的 i − j i-j i−j 个盘子在三塔情况下移动到 D D D(因为 B B B 塔上有一堆小盘子,不能移),最后将那 j j j 个盘子在四塔情况下移动到 D D D 。
所以: f [ i ] = min 0 < = j < = n ( 2 ∗ f [ j ] + d [ n − j ] ) f[i] = \min_{0<=j<=n} {(2*f[j]+d[n-j])} f[i]=0<=j<=nmin(2∗f[j]+d[n−j])
代码
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int n,d[20],f[20];
int main(){
printf("1\n"); //输出n=1时的情况
d[1] = f[1] = 1;
for(int i = 2; i <= 12; ++i) //如上所述
d[i] = 2 * d[i-1] + 1;
for(int i = 2; i <= 12; ++i){
f[i] = 10000000;
for(int j = 1; j < i; ++j)
f[i] = min(f[i],(2 * f[j] + d[i-j]));
printf("%d\n",f[i]);
}
}