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 ...
随机推荐
- 导出数据之CSV
平常开发中,常见的需求就是导出数据为Excel,CSV格式的表格.所以,在此记录一下导出CSV数据的小方法 $fileName = 'demo.csv'; $data = [ ['id'=>1, ...
- VS如何在调试时进入到dll文件
背景: 项目A:用C#写的一个类库文件 项目B:引用项目A的dll文件,完成编码,也是C#编写的. 需求:怎么能在调试的时候,调试断点能够从项目B中进入项目A中的代码. 解决办法就是: 假设,项 ...
- 【面试】MySQL的事务和索引
MySQL事务 MySQL事务主要用于处理操作量大,复杂度高的数据. 比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这些数据库操作 ...
- day 7-12 数据库的基本操作和存储引擎
一. 储备知识 数据库服务器:一台高性能计算机 数据库管理系统:mysql(mssql等),是一个软件 数据库:db1(student_db),是一个文件夹 表:studen_info 是一个文件 记 ...
- jenkins和jdk版本问题
问题:公司业务是用的jdk1.7的,但最新版的jenkins (jenkins-2.138.2-1.1.noarch.rpm)却只支持jdk1.8 分析: 1.公司业务用的jdk1.7不能换,不然影响 ...
- 如何抓取电商的数据 & Python
如何抓取电商的数据 & Python https://www.zhihu.com/question/40720286 https://www.zhihu.com/question/382455 ...
- 织梦后台如何生成站点地图sitemap.xml
第一步在网站根目录建立sitemap.php文件 内容如下: 写一个计划任务文件命名为generate_sitemap.php,放在/plus/task目录里,文件内容如下: <?php//定时 ...
- python设计模式第二十三天【状态模式】
1.应用场景 (1)通过改变对象的内部状态从而改变对象的行为,一般表现为状态的顺序执行 2.代码实现 #!/usr/bin/env python #!_*_ coding:UTF-8 _*_ from ...
- fiddler 学习笔记1-下载安装、开启、关闭抓包功能
1 下载安装(安装于C盘之外的空间中) https://www.telerik.com/fiddler 2 开启抓包功能:安装后默认为开启状态 点击 file-capture 或左下角capture ...
- 魔术方法之__call与__callStatic方法
<?php class human{ private function t(){ } /** * 魔术方法__call * * @param string $method 获得方法名 * @pa ...