Gym-100451B:Double Towers of Hanoi
题目大意:把汉诺双塔按指定顺序排好的最少步数
我写这题写了很久...终于发现不dp不行
把一个双重塔从一根桩柱移动到另一根桩柱需要移动多少次?
最佳策略是移动一个双重 (n-1) 塔,接着移动两个最大的圆盘,然后再次移动双重 (n-1) 塔,从而 $A_n = 2 * A_{n-1} + 2,A_n = 2^{n+1} - 2 $。
这会交换两个最大的圆盘,其余的 \(2n-2\) 个圆盘次序不变。
如果在最后的排列中要把所有同样尺寸的圆盘恢复成原来的从上到下的次序,需要移动多少次?
有两个想法:(假设初始盘子都在A柱上)
一:先把双重(n-1)塔按顺序在C柱上搞好,再2步把最大的两个盘丢到B柱上,\(A_{n-1}\)步把双重(n-1)塔丢A柱子上,再2步把最大的两个盘丢到C柱上,最后\(A_{n-1}\)步把双重(n-1)塔丢C柱子上
发现这样顺序刚好是对的\(B_n=B_{n-1}+2^{n+1}\)
二:先把双重(n-1)塔按顺序在C柱上搞好,再移动靠上的一个大圆盘J到B柱,把(n-1)塔再移上B柱上的大圆盘,移动另一个大圆盘H,把(n-1)塔移到一根空柱上,把H放在J上,再把(n-1)塔移到两个大圆盘上,发现顺序刚好也是对的
\(B_n = A_{n-1} + 1 + A_{n-1} + 1 + A_{n-1} + 1 + A_{n-1} = 4A_{n-1} + 3 = 4(2^{n} - 2) + 3 = 2^{n+2} - 5\)
然后你发现这两个式子是等价的。。。
我的想法:除了最底下的两个盘子,如果两个盘子的顺序是倒过来的,那么在移动的时候就先正着与比它小的盘子放好一堆,在移动更大的两个盘子的时候用\(A_n\)的做法,顺序不就又倒过来了吗?
事实证明这是错的,无法保证最优性
所以dp吧
g[i]表示把前\(2(i-1)\)块按顺序排好,最后两块也按要求顺序排好的最小步数
f[i]表示把前\(2(i-1)\)块按顺序排好,最后两块与要求顺序相反最小步数
\(f[i]=g[i-1]+4+2^{i+1}-4=g[i-1]+2^{i+1}\)
表示先把i-1层按顺序移出去,再移动第i层,i-1层移到另一个柱上,再移动第i层,i-1层移到第i层上,这样顺序刚好是对的(类似\(B_i\)的移法)
\(g[i]=f[i-1]+2+ 2^i-2=f[i-1]+ 2^i\)
表示先把i-1层移出去,再把i层的两个盘移出,再把i-1层移上去
结合代码理解
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;++i)
using namespace std;
typedef long long ll;
typedef double db;
char cch;
inline int rd(){
int x=0,fl=1;
cch=getchar();
while(cch>'9'||cch<'0'){
if(cch=='-') fl=-1;
cch=getchar();
}
while(cch>='0'&&cch<='9') x=(x<<3)+(x<<1)+cch-'0',cch=getchar();
return x*fl;
}
inline void add(int a[],int b[]){
int x=0,len=max(a[0],b[0]);
rep(i,1,len){
a[i]+=b[i]+x,x=a[i]/10000,a[i]%=10000;
}
if(x) a[++len]=x;
a[0]=len;
}
int p[2009][2009],f[2009],g[2009],a[4009];//注意是4009!
int main(){
int n=rd();
p[0][0]=1,p[0][1]=1;
rep(i,1,n+1) add(p[i],p[i-1]),add(p[i],p[i-1]);
rep(i,1,n) a[2*(n-i+1)]=rd(),a[2*(n-i+1)-1]=rd();
if(a[1]<a[2]) g[0]=1,g[1]=3,f[0]=1,f[1]=2;
else g[0]=1,g[1]=2,f[0]=1,f[1]=3;
int *ff=f,*gg=g;//这样可以只swap指针,swap数组是o(n)的
rep(i,2,n){
if(a[i*2]<a[i*2-1]) swap(ff,gg),add(ff,p[i+1]),add(gg,p[i]);//g是2 1顺序,f是1 2顺序,f[i]=g[i-1]+2^{i+1},g[i]=f[i-1]+2^i,所以swap
else add(ff,p[i]),add(gg,p[i+1]);//g是1 2,f是2 1, 此时g相当于上面的f,f相当于上面的g,所以转移方程互换
}
printf("%d",gg[gg[0]]);
for(int i=gg[0]-1;i;--i) printf("%04d",gg[i]);
}
/*
4
8 7 5 6 3 4 1 2
*/
Gym-100451B:Double Towers of Hanoi的更多相关文章
- POJ1958:Strange Towers of Hanoi
我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html 题目传送门:http://poj.org/problem?id=1958 题目要我们求四柱 ...
- The Towers of Hanoi Revisited---(多柱汉诺塔)
Description You all must know the puzzle named "The Towers of Hanoi". The puzzle has three ...
- [CareerCup] 3.4 Towers of Hanoi 汉诺塔
3.4 In the classic problem of the Towers of Hanoi, you have 3 towers and N disks of different sizes ...
- POJ 1958 Strange Towers of Hanoi
Strange Towers of Hanoi Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3784 Accepted: 23 ...
- ural 2029 Towers of Hanoi Strike Back (数学找规律)
ural 2029 Towers of Hanoi Strike Back 链接:http://acm.timus.ru/problem.aspx?space=1&num=2029 题意:汉诺 ...
- POJ1958 Strange Towers of Hanoi [递推]
题目传送门 Strange Towers of Hanoi Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3117 Ac ...
- poj 1920 Towers of Hanoi
Towers of Hanoi Time Limit: 3000MS Memory Limit: 16000K Total Submissions: 2213 Accepted: 986 Ca ...
- zoj 2338 The Towers of Hanoi Revisited
The Towers of Hanoi Revisited Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge You all mus ...
- POJ 1958 Strange Towers of Hanoi 解题报告
Strange Towers of Hanoi 大体意思是要求\(n\)盘4的的hanoi tower问题. 总所周知,\(n\)盘3塔有递推公式\(d[i]=dp[i-1]*2+1\) 令\(f[i ...
随机推荐
- Proper usage of Java -D command-line parameters
https://stackoverflow.com/questions/5045608/proper-usage-of-java-d-command-line-parameters https://c ...
- jmeter环境配置
Java 8 安装 正常安装,一路默认就好,记住安装路径,配置环境变量时用得到.默认安装路径:C:\Program Files\Java\jdk1.8.0_91. 安装好之后会有两个文件夹一个是jdk ...
- mybatis二级缓存详解
1 二级缓存简介 二级缓存是在多个SqlSession在同一个Mapper文件中共享的缓存,它是Mapper级别的,其作用域是Mapper文件中的namespace,默认是不开启的.看如下图: 1. ...
- 转:Flutter Decoration背景设定(边框、圆角、阴影、形状、渐变、背景图像等)
1 继续关系: BoxDecoration:实现边框.圆角.阴影.形状.渐变.背景图像 ShapeDecoration:实现四个边分别指定颜色和宽度.底部线.矩形边色.圆形边色.体育场(竖向椭圆). ...
- 前端开发之css
<!--页面中的组成部分通常随便打开一个网页,有文字,图片,视频,表格,音频,表单(注册信息) css 属性/尺寸/边框/背景 1.css的尺寸属性,就是大小width max-width mi ...
- springboot项目小总结
使用模板引擎 thyemlef 可以直接将 html文件进行导入 loginhtml文件 html中常用的表达式 <link href="asserts/css/signin.cs ...
- 18个Python高效编程技巧,Mark!
初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...
- 面对AI
面对AI,我们应该怎么做? 李开复博士的一段话: 1. 我们应该具有战略性思维,并以人工智能无法取代的工作为目标.我们应该致力于终身学习,更新我们的技能,了解新趋势,并寻找新机遇. 2. 我们应该鼓励 ...
- adoquery.refresh和adoquery.query的区别
大的区别没有 1: requery是通过重新发出原始命令并再次检索数据,可使用 Requery 方法刷新来自数据源的 Recordset 对象的全部内容.调用该方法等于相继调用 Close 和 Ope ...
- 神烦之float
另外一篇文章 : css float 一 历史 Float的设计初衷仅仅是:文字环绕效果(向word中的文字环绕效果) 二 特性 1.包裹性:块级元素如果不设置float,它默认会撑满整个屏幕,而如果 ...