汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI
汉诺塔II hdu1207:
先说汉若塔I(经典汉若塔问题),有三塔。A塔从小到大从上至下放有N个盘子。如今要搬到目标C上。
规则小的必需放在大的上面,每次搬一个。求最小步数。
这个问题简单,DP:a[n]=a[n-1]+1+a[n-1],先把
上面的n-1个放在B上,把最大的放在目标C上,再把N-1个放回到C上就可以。
网上的一种最优解法例如以下:(1)将x(1<=x<=n)个盘从a柱依靠b,d柱移到c柱。这个过程须要的步数为F[x];(2)将a柱上剩下的n-x个盘依靠b柱移到d柱(注:此时不可以依靠c柱,由于c柱上的全部盘都比a柱上的盘小) 些时移动方式相当于是一个经典汉诺塔。即这个过程须要的步数为2^(n-x)-1(证明见再议汉诺塔一);(3)将c柱上的x个盘依靠a,b柱移到d柱上,这个过程须要的步数为F[x];第(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的各个取值,并用一个标记变量min记录x的各个取值中F[n]的最小值。
#include"stdio.h"
#include"string.h"
#include"math.h"
#define N 66
#define Inf 0x7fffffff
int main()
{
__int64 i,j,min,f[N]={0,1,3};;
for(i=3;i<N;i++)
{
min=Inf;
for(j=1;j<i;j++)
{
if(min>2*f[j]+pow(2.0,1.0*i-j)-1) //pow的返回值会超出64位。不能强制转换为整数
min=2*f[j]+pow(2.0,1.0*i-j)-1; //注意两个參数应该都为double型。! }
f[i]=min;
}
while(scanf("%I64d",&i)!=-1)
{
printf("%I64d\n",f[i]);
}
return 0;
}
汉若塔III hdu2064:
先把上面的N-1个移动到C(必定有这个状态)。在把最大的移到B,再把N-1移到到A。把最大的移到C,再把N-1个移到C。
递推公式:f[n]=f[n-1]+1+f[n-1]+1+f[n-1]; 即f[n]=3*f[n-1]+2;
#include"stdio.h"
#include"string.h"
#include"math.h"
#define N 36
int main()
{
__int64 n,i,f[N]={2};
for(i=1;i<N;i++)
{
f[i]=3*f[i-1]+2;
}
while(scanf("%I64d",&n)!=-1)
{
printf("%I64d\n",f[n-1]);
}
return 0;
}
汉若塔IV HDU 2077
在汉若塔3的基础上。改条件:同意最大的盘子放到最上面(仅仅同意最大的放在最上面)当然最后须要的结果还是盘子从小到大排在最右边。
A,B,C三个塔。方程:ans[n]=ab[n-1]+1+1+bc[n-1]. (ab表示a到b)
DP思路:先把n-1个搬到b,再用俩步般最大的到C。再把n-1个从B到C。这里又要求出ac[n]和bc[n]:求其递推方程:bc[n]=bc[n-1]+1+ac[n-1],(1式)
会发现bc[n]方程和ab[n]一样的。
所以总方程ans[n]=2*bc[n-1]+2. (2式)
#include"stdio.h"
#include"string.h"
#include"math.h"
#define N 21
int main()
{
int i,T;
__int64 ac[N],bc[N],ans[N];
ac[1]=2;
bc[1]=1;
for(i=2;i<N;i++)
{
ac[i]=3*ac[i-1]+2;
bc[i]=bc[i-1]+ac[i-1]+1;
ans[i]=2*bc[i-1]+2;
}
ans[1]=2;
scanf("%d",&T);
while(T--)
{
scanf("%d",&i);
printf("%I64d\n",ans[i]);
}
return 0;
}
汉若塔V HDU1995
在经典汉若塔问题上附加问题:求出N个盘子时,第K号盘子的移动次数。
思路。一想就是二维DP,DP[n][i]=dp[n-1][i]*2(1=<i<n),dp[n][n]=1;
最大盘仅仅移动一次,上面盘子先移到B塔,一次,最后由B到目标C重新.。
#include"stdio.h"
#include"string.h"
#include"math.h"
#define N 61
int main()
{
__int64 i,j,f[N][N];
f[1][1]=f[2][2]=1;
f[2][1]=2;
for(i=3;i<N;i++)
{
f[i][i]=1;
for(j=1;j<i;j++)
{
f[i][j]=2*f[i-1][j];
}
}
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
printf("%I64d\n",f[n][m]);
}
return 0;
}
汉若塔VI HDU1996
每一个盘从小到大每一个都有3种选择,共3^n。
#include"stdio.h"
#include"string.h"
#include"math.h"
#define N 61
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("%.0f\n",pow(3.0,n*1.0));
}
return 0;
}
汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI的更多相关文章
- 里诺全系列注册机+暗桩patch
一直有坛友私信更新里诺,今天花了一天时间,将里诺全系列更新完毕,权当送给坛友们的新年礼物吧! 全系列开放至元旦假期结束,后面就随机开放了. <ignore_js_op> 使用说明: 1.选 ...
- 《Mastering Opencv ...读书笔记系列》车牌识别(II)
http://blog.csdn.net/jinshengtao/article/details/17954427 <Mastering Opencv ...读书笔记系列>车牌识别(I ...
- HDU 汉诺塔系列
做了这一系列题,表示对汉诺塔与这一系列递推理解加深了 经典汉诺塔:1,2,...,n表示n个盘子,数字大盘子就大,n个盘子放在第1根柱子上,按照从上到下 从小到大的顺序排放,过程中每次大盘都不能放在小 ...
- HDU汉诺塔系列
这几天刷了杭电的汉诺塔一套,来写写题解. HDU1207 汉诺塔II HDU1995 汉诺塔V HDU1996 汉诺塔VI HDU1997 汉诺塔VII HDU2064 汉诺塔III HDU2077 ...
- 汉若塔系列续:汉诺塔VIII、汉诺塔IX、汉诺塔X。
汉诺塔VIII,在经典汉若塔问题上,问n个盘子的情况下,移动m次以后,是什么状态.(与第七代互为逆命题) 我的思路:本质还是dfs,但是用m的值来指引方向,每搜一层确定第i个盘子在哪个塔,o(n)的算 ...
- [LeetCode系列]链表环探测问题II
给定一个链表头, 探测其是否有环, 如果没有返回NULL, 如果有返回环开始的位置. 环开始的位置定义为被两个指针指向的位置. 算法描述: 1. 快慢指针遍历, 如果到头说明无环返回NULL, 如果相 ...
- FlasActionScript3随学随机
1.跳转页面代码.下载代码(new URLRequest(下载地址)): var request1:URLRequest=new URLRequest("http://www.baidu.c ...
- N.O.W,O.R,N.E.V.E.R--12days to LNOI2015
双向链表 单调队列,双端队列 单调栈 堆 带权并查集 hash 表 双hash 树状数组 线段树合并 平衡树 Treap 随机平衡二叉树 Scapegoat Tree 替罪羊树 朝鲜树 块状数组,块状 ...
- 1019: [SHOI2008]汉诺塔
1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1495 Solved: 916[Submit][Status] ...
随机推荐
- 数据特征分析:3.统计分析 & 帕累托分析
1.统计分析 统计指标对定量数据进行统计描述,常从集中趋势和离中趋势两个方面进行分析 集中趋势度量 / 离中趋势度量 One.集中趋势度量 指一组数据向某一中心靠拢的倾向,核心在于寻找数据的代表值或中 ...
- C++中全排列算法函数next_permutation的使用方法
首先,先看对next_permutation函数的解释: http://www.cplusplus.com/reference/algorithm/next_permutation/?kw=next_ ...
- 用sql的avg(score)求完平均值后,保存两位小数的方法(用于查询或视图)
查jx_score表的平均值,以哪次考试(testid)和科目分组(courseid) select testid, courseid, round(avg(`jx_score`.`score`),2 ...
- P3353 在你窗外闪耀的星星
飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的脸颊.我明 ...
- linux 命令基础一。
UNIX是什么 UNIX的定义: UNIX是一个计算机操作系统,一个用来协调.管理和控制计算机硬件和软件资源的控制程序. UNIX操作系统的特点:多用户和多任务多用户表示在同一时刻可以有多个用户同时使 ...
- SQL 自定义四舍五入
--============================================== -- 自定义的四舍五入(四舍五入后的所有尾数遇进则进) -- by 小天使 2015-11-12 -- ...
- gcc 各种参数
1简介 2简单编译 2.1预处理 2.2编译为汇编代码(Compilation) 2.3汇编(Assembly) 2.4连接(Linking) 3多个程序文件的编译 4检错 5库文件连接 5.1编译成 ...
- js 函数与类的区别
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mongodb更新数组元素中的字段,数组$占位符
pppCodes为数组,PPPCode,expiredOn为数组元素中的字段 db.getCollection('users').findOneAndUpdate({ _id: userId, 'pp ...
- js数组根据指定字段(true or false)排序
const obj = [ {name:'1',bind:true}, {name:'2',bind:false}, {name:'3',bind:true}, {name:'4',bind:fals ...