汉诺塔IV
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4476 Accepted Submission(s): 3282
Problem Description 还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。
Input 输入数据的第一行是一个数据T,表示有T组数据。
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。
Output 对于每组输入数据,最少需要的摆放次数。
Sample Input
2 1 10
Sample Output
2 19684
转载汉诺塔||| 的一个结题报告题解:http://www.acmerblog.com/hdu-2064-III-3197.html
这题首先我们应该知道的是如何将N个圆盘从第一杆全部搬到第二根杆跟全部搬到第三根杆和从第二根杆全部搬到第三根杆需要的次数是一样的,然后搬N根杆的次数就可以有搬N-1根杆的次数得到,这里首先给出地推公式,dp[n]=3*dp[n-1]+2;思想就是假设现在要将N个圆盘搬到第三根杆,现在首先要做的是把N-1根杆全部搬到第三根杆,这样一共需要dp[n-1]次,然后第一根杆上面还剩下一个圆盘,现在我们要把这最后一个圆盘放到第二根杆上面,原因待会再解释,然后现在要做的事就是把这一个最大的圆盘放到第三根杆的最下面,然而第三根杆现在正被N-1个圆盘占用了,所以要将这N-1个圆盘移开全部移到第一根杆上面,所以这样需要的次数是dp[n-1]次,好了,现在第三根杆就完全是空的了,就顺利地把最后一个圆盘放到第三根杆上面了,这时再把N-1个圆盘从第一根杆上面移动到第三根杆上面,这样整个游戏就结束了。现在解释一下为什么第二步要把最大的那个盘移动到第二根杆了,很显然如果这一步不把它移到第二根杆的话,那么第三根杆上面的N-1个盘就必须移动到第二根杆上面,而这时最大的盘还在第一根杆上又不可以把它直接移动到第三根杆上面,又不能移到第二根杆上面,因为大盘不能放小盘上面,所以第二步就只好把最大的盘放到第二根杆上面。
而汉诺塔四相对其来说,只是最后一步转移时,可以改为:n-1个圆盘从A移到B、之后令A上最大的盘子经过B移到C,之后令n-1个B上的盘子转移到C上,此时即可完成,反映在代码中,就是递推式的最后一步有所变化。
ACCode:
int n,t;
while(scanf("%d",&t)!=EOF){
while(t--){
scanf("%d",&n);
f[1] = 2;
for(int i=2;i<n;i++){
f[i] = f[i-1]*3 + 2;
}
f[n] = f[n-1] + 2;
printf("%d\n",f[n]);
}
}