BZOJ1019: [SHOI2008]汉诺塔
来源:互联网 发布:导出数据库命令 编辑:程序博客网 时间:2024/05/21 18:49
这题有一个挺厉害的DP解法
一共有三根柱子,编号a,b,c
考虑一开始n个盘子堆在第a个柱子上,
他们全部移到另一柱子的充要条件时第n个盘子即最下的盘子移动
第n个盘子移动的充要条件是他上面的n-1个盘子全部移到另一柱子b,那么根据题目的约束,这时候只能移动第n个盘子到剩下的空柱子c上
移动后,根据约束,只能移动那n-1个盘子
有2种情况:
1:n-1个盘子移到c上,结束操作
2:n-1个盘子移到a上,继续上文的操作
保证有解就不用判死循环了
所以,计算f[i][j],g[i][j]表示i个盘子,在第j个柱子上,全部移到另一个柱子需要步数,会移到哪个柱子,转移的话按照上文讨论一下就好了
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void swap(int &x,int &y){x^=y;y^=x;x^=y;}inline int read(){ char c; int x; while(!((c=getchar())>='0'&&c<='9')); x=c-'0'; while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0'; return x;}const int maxn = 40;char str[10];int dx[7],dy[7];ll f[maxn][4]; int g[maxn][4];int n;int main(){ n=read(); for(int i=1;i<=6;i++) { scanf("%s",str); if(str[0]=='A') dx[i]=1; if(str[0]=='B') dx[i]=2; if(str[0]=='C') dx[i]=3; if(str[1]=='A') dy[i]=1; if(str[1]=='B') dy[i]=2; if(str[1]=='C') dy[i]=3; } for(int i=1;i<=3;i++) for(int j=1;j<=6;j++)if(dx[j]==i) { f[1][i]=1ll; g[1][i]=dy[j]; break; } for(int i=2;i<=n;i++) for(int j=1;j<=3;j++) { int t1=g[i-1][j]; f[i][j]=f[i-1][j]; int t2; for(t2=1;t2<=3;t2++) if(t2!=j&&t2!=t1) break; f[i][j]++; f[i][j]+=f[i-1][t1]; t1=g[i-1][t1]; g[i][j]=t1; while(t1!=t2) { for(int k=1;k<=3;k++) if(k!=t1&&k!=t2) {t2=k;break;} f[i][j]++; f[i][j]+=f[i-1][t1]; t1=g[i-1][t1]; g[i][j]=t1; } } printf("%lld\n",f[n][1]); return 0;}
0 0
- bzoj1019: [SHOI2008]汉诺塔 dp
- BZOJ1019: [SHOI2008]汉诺塔
- 【bzoj1019】[SHOI2008]汉诺塔
- BZOJ1019 [SHOI2008]汉诺塔
- [BZOJ1019][SHOI2008]汉诺塔
- [BZOJ1019][SHOI2008]汉诺塔
- bzoj1019: [SHOI2008]汉诺塔
- 【bzoj1019】[SHOI2008]汉诺塔
- bzoj1019 [SHOI2008]汉诺塔
- bzoj1019: [SHOI2008]汉诺塔
- BZOJ1019: [SHOI2008]汉诺塔
- [BZOJ1019][SHOI2008]汉诺塔
- bzoj1019: [SHOI2008]汉诺塔
- [bzoj1019]:[SHOI2008]汉诺塔
- [BZOJ1019][SHOI2008]汉诺塔(递推)
- [递推] BZOJ1019: [SHOI2008]汉诺塔
- [bzoj1019][递推]汉诺塔
- BZOJ1019
- 二分图最大匹配
- Activity横竖屏切换后的生命周期
- C# 如何给Winform的button等控件添加快捷键
- (转)2017:整合欧美中小型资产管理公司的元年及如何突出重围
- Matlab 2015b 并行运算 SPMD
- BZOJ1019: [SHOI2008]汉诺塔
- 使用var、let、const声明变量
- 关于PHP程序员技术职业生涯规划
- c语言指针与函数形参和实参易错点总结
- iOS类似Android点9图拉升
- Shell wait命令
- 51nod 1138 连续整数的和(数学)
- 访问权限控制
- 自然语言处理中的Attention Model:是什么及为什么