【Ybtoj 第1章 例题2】汉诺塔问题【递推】

题目描述

这里有 A、B、C 和 D 四座塔。
这里有 个圆盘, 的数量是恒定的。
每个圆盘的尺寸都不相同。
所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。 请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。


输入格式
没有输入。

输出格式
对于每一个整数 n ( 1 < = n < = 12 n(1<=n<=12 n1<=n<=12,输出一个满足条件的最小移动次数,每个结果占一行。


解题思路

首先考虑3座塔的汉诺塔问题,我们设 d ( n ) d(n) dn表示n个盘子3座塔的最优步数,我们需要先把 n − 1 n-1 n1个盘子移到B柱上,最优步数为 d ( n − 1 ) d(n-1) dn1,然后把A柱上的剩余的一个盘子移到C柱上,步数为1,最后把B柱上的 n − 1 n-1 n1个盘子移到C柱上,最优步数也为 d ( n − 1 ) d(n-1) dn1。固有递推式: d ( n ) = 2 ∗ d ( n − 1 ) + 1 d(n)=2*d(n-1)+1 d(n)=2d(n1)+1

回到本题,设 f ( n ) f(n) fn表示n个盘子4座塔的最优步数,考虑从A柱移动 j ( 0 < = j < = n ) j(0<=j<=n) j0<=j<=n个盘子到B柱上,最优步数为 f ( j ) f(j) fj。再将 n − j n-j nj个盘子移动到D柱上,考虑B柱上圆盘尺寸小,不能放盘子了,故变成了3塔模式,最优步数为 d ( n − j ) d(n-j) dnj,最后再将j个盘子移动到D柱上,最优步数为 f ( j ) f(j) fj。考虑所有的j,固有递推式: f ( n ) = m i n ( 2 ∗ f ( j ) + d ( n − j ) , f ( n ) f(n)=min{(2*f(j)+d(n-j),f(n)} fn=min(2f(j)+d(nj),f(n)


代码

#include<iostream>
#include<cstdio>
using namespace std;
const int INF=2147483600;
int d[20],f[20];
int main(){
    
    
	d[1]=1;
	for(int i=2;i<=12;i++)
	 	d[i]=d[i-1]*2+1;
	f[1]=1;
	printf("%d\n",f[1]);
	for(int i=2;i<=12;i++)
	{
    
    
		f[i]=INF;
		for(int j=1;j<=i;j++)
			f[i]=min(f[i],2*f[j]+d[i-j]);
		printf("%d\n",f[i]);
	}
}

猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/111598352
今日推荐