汉诺塔问题
递推:
简单:n盘 3塔
假设现在有a,b,c三个塔。路线:a塔所有盘子要移动到c塔。设s[n]为最少步数。
假设有三个盘。1号,2号,3号
state(初始状态):
a盘:1号盘在最上面,3号在最底下。
b盘:无
c盘:无
要想把最后一个移出来,就要把上方n-1个盘子一走。即s[n]=1(最后一个盘子没有阻碍情况下从a至c只需一步)+s[n-1](n-1个移动到b先)+s[n-1](移动完最底下后n-1个从b到c)
最后得出递推公式,三塔情况下 s[n]=1+2*s[n-1]
开始模拟:
1(a->c)
2(a->b)
1(c->b)
3(a->c)
1(b->a)
2(b->c)
1(a->c)
提高难度:n盘4塔 路线:a塔到d塔。
递推公式:f[n]=f[i]*2+d[i-j]
先把i个盘子在4塔模式下移动到b柱 同三塔思路--------f[i]*2
然后把n-i个盘子在3塔模式下移动到d柱(因为不能覆盖到b柱上,就等于只剩下a、b、d柱可以用)-------d[i-j]
汉诺塔问题,条件如下:
1、这里有 A、B、C 和 D 四座塔。
2、这里有 n 个圆盘,n 的数量是恒定的。
3、每个圆盘的尺寸都不相同。
4、所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
5、我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
6、每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。
请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。
输入格式
没有输入
输出格式
对于每一个整数 n,输出一个满足条件的最小移动次数,每个结果占一行。
数据范围
1≤n≤12
输入样例:
没有输入
输出样例:
参考输出格式
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int d[20], f[20];
int main() {
d[1] = 1;//赋初值
for (int i = 2; i <= 12; i++)
d[i] = 2 * d[i - 1] + 1;//三塔公式
memset(f, 0x3f, sizeof(f));
f[0] = 0;//赋初值
for (int i = 1; i <= 12; i++)//i从1开始
for (int j = 0; j < i; j++)
f[i] = min(f[i], 2 * f[j] + d[i - j]);
for (int i = 1; i <= 12; i++)
cout << f[i] << endl;
return 0;
}