[递推]B. 【例题2】奇怪汉诺塔

B . 【 例 题 2 】 奇 怪 汉 诺 塔 B. 【例题2】奇怪汉诺塔 B.2

题目描述

汉诺塔问题,条件如下:

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

输入格式

没有输入。


输出格式

对于每一个整数 n ( 1 ≤ n ≤ 12 ) n(1 ≤ n ≤ 12) n(1n12),输出一个满足条件的最小移动次数,每个结果占一行。


题目解析

看题目,是汉诺塔,只是常规的三塔变成了四塔.
那么我们就考虑四塔的做法.

首先我们定义 d i d_{i} di为三塔时 n n n个盘从 A A A塔到 C C C塔所需的步数.
那么可以得出(证明略):
d 1 = 1 d_{1} = 1 d1=1

d i = d i − 1 ∗ 2 − 1                ( i > 1 ) d_{i} = d_{i-1}*2-1~~~~~~~~~~~~~~(i>1) di=di121              (i>1)

然后我们定义 f ( i ) f(i) f(i)为四塔汉诺塔的最优步数为考虑四塔汉诺塔的算法思想,叫Frame算法:

  1. 用四柱汉诺塔算法把 A A A柱上部分的 n − r n- r nr个碟子通过 C C C柱和 D D D柱移到 B B B柱上( f ( n − r ) f( n- r ) f(nr))。

  2. 用三柱汉诺塔经典算法把 A A A柱上剩余的 r r r个碟子通过 C C C柱移到 D D D柱上(三塔汉诺塔 r r r盘的步数)。

  3. 用四柱汉诺塔算法把 B B B柱上的 n − r n-r nr个碟子通过 A A A柱和 C C C柱移到 D D D柱上( f ( n − r ) f(n-r) f(nr))。

  4. 依据上边规则求出所有 r ( 1 ≤ r ≤ n ) r(1≤r≤n) r(1rn)情况下步数 f ( n ) f(n) f(n),取最小值得最终解。

f [ i ] = m i n { f [ i ] 2 ∗ f [ j ] + d [ i − j ] f[i] = min \left\{\begin{matrix} & f[i]\\ & 2 * f[j] + d[i - j]\\ \end{matrix}\right. f[i]=min{f[i]2f[j]+d[ij]


Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll d[305], f[305]; 

int main ()
{
	d[1] = f[1] = 1;
	for (int i = 2; i <= 12; ++ i) 
		d[i] = d[i - 1] * 2 + 1;	 
	for (int i = 2; i <= 12; ++ i)
	{
		f[i] = 999999999;
		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;
}
posted @ 2020-12-20 11:16  unknown_future  阅读(63)  评论(0编辑  收藏  举报