解题报告:在汉诺塔的基础上,规定,第一根柱子上的盘不能直接移动到第三根柱子,就是说只能从第二根柱子移出,或者移到第二根柱子,然后规定只有最大的盘子可以放在最小的盘子上,要求将n个盘子从第一根柱子移动到第三根柱子,问最少需要多少步?
还是一样dp,只不过这题的一个特别之处就是三根柱子的性质不完全一样,所以在dp第一根柱子移到第三根柱子的时候不能直接用dp[n-1],因为如果把n个盘子从第一根柱子移到第二根柱子跟移到第三个柱子的次数是不一样的,然后我们可以发现,移到第二根柱子或者从第二根柱子移动到其它两根柱子的性质是一样的,所以我们可以先打一个表,即1-n个盘子从第一根柱子到第二根柱子的最少次数。然后再打一次表,假如现在要将n个盘子从第一根柱子移动到第三根柱子,则这个完整的过程如下:
第一步:将n-1个盘子从第一根柱子移动第二根柱子,花费f[n-1]步
第二步:将1个盘子从第一根柱子移到第二根柱子,花费1步
第三步:将1个盘子从第二根柱子移到第三根柱子,花费1步
第四步:将n-1个盘子从第二根柱子移到第三根柱子,花费dp[n-1]步
结束。。
1 //////提交代码 2 3 #include<cstdio> 4 int ans[23] = { 5 0,2,4,10,28,82,244,730,2188,6562,19684,59050,177148,531442,1594324,4782970,14348908,43046722,129140164,387420490,1162261468}; 6 7 int main() { 8 int T,n; 9 scanf("%d",&T); 10 while(T--) { 11 scanf("%d",&n); 12 printf("%d ",ans[n]); 13 } 14 return 0; 15 } 16 17 ///////打表代码 18 19 /*#include<cstdio> 20 #include<cstring> 21 int dp[30],f[30]; 22 int ans[23] = { 23 0,2,4,10,28,82,244,730,2188,6562,19684,59050,177148,531442,1594324,4782970,14348908,43046722,129140164,387420490,1162261468}; 24 void dabiao0() { 25 f[1] = 1; 26 f[2] = 4; 27 for(int i = 3;i<=20;++i) 28 f[i] = 3 * f[i-1]+1; 29 } 30 void dabiao() { 31 dabiao0(); 32 dp[1] = 2; 33 dp[2] = 4; 34 for(int i = 3;i<=20;++i) 35 dp[i] = 2 * f[i-1] + 2; 36 } 37 38 int main() { 39 int T,n; 40 freopen("out.txt","w",stdout); 41 dabiao(); 42 scanf("%d",&T); 43 while(T--) { 44 scanf("%d",&n); 45 printf("%d, ",dp[n]); 46 } 47 return 0; 48 } */ 49