奇怪汉诺塔【DP】

>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 i1个盘搬到 B B B(三个塔,代价为 d i − 1 d_{i-1} di1),再把第 i i i个盘搬到 C C C(代价为1),最后把 i − 1 i-1 i1个盘从 B B B搬到 C C C
所以 d i = 2 ∗ d i − 1 + 1 d_i=2* d_{i-1}+1 di=2di1+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 ij个搬到 D D D C C C塔已经被小的盘占用了,所以只有三个塔可以用,代价为 d i − j d_{i-j} dij),最后把 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(2fj+dij)


>代码

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_43010386/article/details/111715459