题目链接:http://sfxb.openjudge.cn/dongtaiguihua/E/
题目描述:4个柱子的汉诺塔,求盘子个数n从1到12时,从A移到D所需的最大次数。限制条件和三个柱子的汉诺塔问题相同。
解题思路:采用动态规划算法的思路为先从将k个盘子使用4个柱子的方法从A移到B,然后将A上剩下的n-k个盘子使用3个柱子的方法移到D上,然后再使用4个柱子的方法将B上的k个盘子移到D上。可以明白这道题会产生很多重复子问题。所以先计算出使用3个柱子的方法从A移到B的次数用数组f3保存。然后计算n=1到12时,k从1到i-1变化时,f4[n]的大小。计算过程满足下边的方程f4[n]=min(1≤k<i)(f3[k]+2*f[i-k]);当n=1时,f4[1]=1;
代码如下:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<stdlib.h> using namespace std; int f3[13]; int f4[13]; int three_hoi(int x){ if(x==1)return 1; return 2*three_hoi(x-1)+1; } int main(){ for(int i=1;i<=12;i++){ f3[i]=three_hoi(i); } f4[1]=1; // memset(f4,-1,sizeof(f4)); for(int i=2;i<=12;i++){ f4[i]=65536; } for(int i=2;i<=12;i++){ for(int j=i-1;j>=1;j--){ int t=f3[j]+2*f4[i-j]; if(t<f4[i]){ // cout<<f4[i]<<"f4"; f4[i]=t; // cout<<i<<"i"<<j<<"j"; // cout<<t<<"t"<<endl; } } } // for(int i=1;i<=12;i++){ // printf("%d ",f3[i]); // } // system("pause"); for(int i=1;i<=12;i++){ printf("%d ",f4[i]); } return 0; }
对于给定的n,算法时间复杂度为O(n).