码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 1207 汉诺塔II

时间:2015-03-16 21:18:09      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:c++   算法   编程   acm   c   

解析:

1、先看汉诺塔1的情况

a、只有一个盘子时,只需挪动一步;
b、假如n个盘子要移动An步,则有n+1个盘子可以先通过An步把上面的n个盘子挪到第二个柱子上,再挪最大的盘子,最后把n个盘子挪到大的上面,总共2An+1步,则有A(n+1)=2An+1。
c、以上式子可推得An=2^n-1。

2、回过来看该題,该题多加了一根柱子,现在有四根柱子了,分别是a,b,c,d,计算将n个盘从第一根柱子a全部移到最后一根柱子d上所需的最少步数,而且不能够出现大的盘子放在小的盘子上面。

a、设F[n]为所求的最小步数,则有当n=1时,F[n]=1;当n=2时,F[n]=3;这里同经典汉诺塔一样,将移动盘子的任务分为三步:

b、将x(1<=x<=n)个盘从a柱依靠b,d柱移到c柱,这个过程需要步数设为F[x];
c、将a柱上剩下的n-x个盘依靠b柱移到d柱(此时不能依靠c柱,c柱上的所有盘都比a柱上的盘小),移动方式相当于是一个汉诺塔1版,这个过程需要的步数为2^(n-x)-1(汉诺塔一);
d、将c柱上的x个盘依靠a,b柱移到d柱上,这个过程同样需要的步数为F[x];
e、经过以上3步即可完成任务,总步数为F[n]=F[x]+2^(n-x)-1+F[x]=2*F[x]+2^(n-x)-1;题目中要求的是最少的步数,根据上式,x的不同取值,对于同一个n,也会得出不同的F[n]。因此答案转化为min{2*F[x]+2^(n-x)-1},其中1<=x<=n;循环遍历x的各个取值,记录最小值即可。


#include<iostream> 
#include<cmath>  
using namespace std;


int main()  
{
	__int64 max=0x7FFFFFFFFFFFFFFF,f[65],min;
	int i,j,n;

	f[1]=1;f[2]=3;
	for(i=3;i<65;i++)
	{
		min=max;
		for(j=1;j<i;j++)
			if(2*f[j]+pow(2.0,i-j)-1<min)
				min=2*f[j]+pow(2.0,i-j)-1;
		f[i]=min;
	}

	while(cin>>n)
	{
		printf("%I64d\n",f[n]);
	}
    return 0;  
}


HDU ACM 1207 汉诺塔II

标签:c++   算法   编程   acm   c   

原文地址:http://blog.csdn.net/a809146548/article/details/44313041

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!