四塔问题:设有A,B,C,D四个柱子(有时称塔),在A柱上有由小到大堆放的n个盘子,如图所示。
今将A柱上的盘子移动到D柱上去。可以利用B,C柱作为工作栈用,移动的规则如下:
①每次只能移动一个盘子。
②在移动的过程中,小盘子只能放到大盘子的上面。
设计并实现一个求解四塔问题的动态规划算法,并分析时间和空间复杂性。
算法思想:
用如下算法移动盘子(记为FourPegsHanoi):
1)、将A柱上n个盘子划分为上下两部分,下方部分共有k(1≤k≤n)个盘子,上方部分共有n - k个盘子。
2)、将A柱上面部分n–k个盘子使用FourPegsHanoi算法经过C、D柱移至B柱。
3)、将A柱剩余的k个盘子使用ThreePegsHanoi算法经过C柱移至D柱。
4)、将B柱上的n–k个盘子使用FourPegsHanoi算法经过A、C柱移至D柱。
注意利用函数返回值求每次的最小值的方式!
#include <iostream>
using namespace std;
///* run this program using the console pauser or add your own getch, system("pause") or input loop */
int hanoi3(int n,char a,char b,char c) //a->c b做中间柱子
{
if(n==1)
{
return 1;
}
int now=0;
now+=hanoi3(n-1,a,c,b);
//printf("%c->%c\n",a,c);
now++;
now+=hanoi3(n-1,b,a,c);
return now;
}
int hanoi4(int n,char a,char b,char c ,char d)
{
if(n==1)
{
//printf("%c->%c\n",a,d);
return 1;
}
int minans=100000;
for(int k=1;k<n;k++)
{
int ans=0;
ans+=hanoi4(n-k,a,c,d,b); //n-k指的是上面那部分,k值得是下面部分
ans+=hanoi3(k,a,c,d);
ans+=hanoi4(n-k,b,a,c,d);
if(ans<minans)
minans=ans;
}
return minans;
}
int main(int argc, char** argv) {
for(int i=1;i<=12;i++)
{
cout << hanoi4(i,'A','B','C','D') << endl;
}
return 0;
}