Strange Towers of Hanoi四塔汉诺塔[POJ1958][递推]
题面
[传送门](http://poj.org/problem?id=1958)
简言之就是解出n个盘子4座塔的Hanoi问题最少需要多少步
分析
对于三塔经典Hanoi问题,有
\[\boxed{d[n] = 2 * d[n -1] + 1}
\]
原理是第一步把n-1个盘子放在另一个塔子上,
第二步把第n个盘子放在另外一个空塔上,
第三步再把n-1个盘子叠上去
如果是四座塔,不妨考虑先把一定数量的盘子放在第四座塔并固定,
然后将剩余的盘子在三塔模式下移到目标位置,
最后将第四座塔的盘子在四塔模式下移到目标位置
实际上是个递推过程
不妨设这个数量为i,f[n]表示求解n盘4塔的最少步数
按照上述分析有
\[\boxed{f[n] = min(2 * f[i] + d[n - i]),1<=i<n}
\]
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
inline int read() {
	register int x = 0, f = 1;
	register char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0',c = getchar();
	return x * f;
}
int d[31],f[31]; 
void init() {//初始化和预处理
	memset(f, 0x3f, sizeof(f));
	f[1] = 1;
	d[1] = 1;
	for (int i(2); i <= 31; i++) d[i] = (d[i - 1] << 1) + 1;
}
void doit() {
	int n = read();
	for (int i(2); i <= n; i++) {
		for (int j(1); j < i; j++){
			f[i] = min(f[i], (f[j] << 1) + d[i - j]);
		}
		printf("%d\n",f[i]);
	}
}
int main() {
	init();
	doit();
	return 0;
}

                
            
        
浙公网安备 33010602011771号