>Link
ybtoj奇怪汉诺塔
>解题思路
设这四个塔为 A , B , C , D A,B,C,D A,B,C,D
先考虑只有三个塔的情况,设 d i d_i di为三个塔时从 A A A搬移 i i i个盘到 C C C的最小步数
最小步数,我们可以先把 i − 1 i-1 i−1个盘搬到 B B B(三个塔,代价为 d i − 1 d_{i-1} di−1),再把第 i i i个盘搬到 C C C(代价为1),最后把 i − 1 i-1 i−1个盘从 B B B搬到 C C C
所以 d i = 2 ∗ d i − 1 + 1 d_i=2* d_{i-1}+1 di=2∗di−1+1
四个塔的情况时,设 f i f_i fi为四个塔时从 A A A搬移 i i i个盘到 D D D的最小步数,
枚举先搬的盘子数 j ( 0 < j < i ) j(0<j<i) j(0<j<i),先把 j j j个盘搬到 C C C(四个塔,代价为 f j f_j fj),再把剩下的 i − j i-j i−j个搬到 D D D( C C C塔已经被小的盘占用了,所以只有三个塔可以用,代价为 d i − j d_{i-j} di−j),最后把 j j j个盘从 C C C搬到 D D D
所以 f i = m i n ( 2 ∗ f j + d i − j ) f_i=min(2*f_{j}+d_{i-j}) fi=min(2∗fj+di−j)
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, d[20], f[20];
int main()
{
memset (f, 0x7f, sizeof (f));
for (int i = 1; i <= 12; i++)
d[i] = 2 * d[i - 1] + 1;
f[1] = 1;
for (int i = 2; i <= 12; i++)
for (int j = 1; j < i; j++)
f[i] = min (f[i], 2 * f[j] + d[i - j]);
for (int i = 1; i <= 12; i++)
printf ("%d\n", f[i]);
return 0;
}