1. 程式人生 > >【POJ1958】【典型遞推問題】漢諾塔問題

【POJ1958】【典型遞推問題】漢諾塔問題

題意:

      給你n個盤子,問在四個柱子的情況下,最少需要多少步才能將n個盤子移動到另一個柱子上。

 

思路:

      先來看看最經典的三個柱子問題。

      f3[i] = 2*f3[i-1]+1,即將(i-1)個盤子移動到中間那根柱子上,然後再將最後一個盤子移動到目標柱子上,最後將(i-1)個盤子移動到目標柱子上即可。

 

      那麼對於四根柱子的話,我們可以先將i個盤子移到B柱子上,然後再將剩下的盤子按照三根柱子的移法移到目標柱子上,然後B柱子上的i個盤子再按四根柱子的移法移動到目標柱子即可。

      所以 f4[n] = min(2*f4[i]+f3[n-i])。

 

總結:

      漢諾塔問題是典型的遞推問題,此問題也可以拓展到m個柱子,n個盤子上,思路都是統一的進行遞推。

 

程式碼:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;

int f3[15],f4[15];

void init()
{
	f3[1] = 1;
	rep(i,2,12)
		f3[i] = 2*f3[i-1]+1;
}

int main()
{
	int n = 12;
	init();
	memset(f4,0x3f,sizeof f4);
	f4[1] = 1;
	rep(i,2,n)
	{
		rep(j,1,i-1)
		{
			f4[i] = min(f4[i],f4[j]+f3[i-j]+f4[j]);
		}
	}
	rep(i,1,12)
		printf("%d\n",f4[i]);
	return 0;
}