POj 3601 Tower of Hanoi 汉诺塔(贪心)
来源:互联网 发布:linux删除进程命令 编辑:程序博客网 时间:2024/05/22 05:01
题意:汉诺塔问题,不过其中加了一个条件,就是盘子可以有相同的
可以发现,当移动第i 种盘子时&& num[i]>=2得到的是逆序的,但是题目要求不能改变顺序,所以必须处理
1.先考虑不按顺序的情况为 dp1[i]=dp1[i-1]*2+num[i] ,num[i]为相同盘子的个数
公式得来:如果从A到C轴,借助B轴,i种盘子,要先把i - 1种移动到 B, 需要dp1[i - 1],然后把第i种移动到C,需要num[i],然后再把i - 1种从B移动到C,需要dp1[i - 1]
所以得到dp1[i]=dp1[i-1]*2+num[i] .
2.考虑按顺序的情况为 dp2[i]=2*dp1[i-1]+2*num[i]+dp2[i-1]
公式得来:把num[1] - 1个移动到辅助轴,这时这num[1] - 1个盘子的顺序颠倒了,然后把第num[1]中最后一个移动到目标轴,然后把辅助轴上的移动回来,再次颠倒,恢复顺序,得到dp2[1] = 2 * (num[1] - 1) +1。
对于dp2[i],
如果x[i] == 1,那么第i种就不需要考虑顺序(只有一种),所以dp2[i] = dp1[i]
否则,第i种要调动2次,保证顺序不变。
还是从A到C轴,借助B轴,i种盘子
把i - 1种不考虑顺序移到C,需要dp1[i - 1].
把第i种从A移动到B,需要num[i](颠倒顺序),
把i - 1种不考虑顺序移到A(腾出C),需要dp1[i - 1].
把第i种从B移动到C,需要num[i](顺序恢复)
把i - 1种考虑顺序移到C,需要dp2[i - 1].
所以有dp2[i] = 2 * dp1[i - 1] +2 * num[i] +dp2[i - 1]
最后答案是dp2[n].
代码:
#include <stdio.h>#include <cstring>using namespace std;int dp1[105];int dp2[105];int num[105];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&num[i]); dp1[1]=num[1];//dp1不考虑顺序 for(int i=2;i<=n;i++) dp1[i]=(2*dp1[i-1]+num[i])%m; dp2[1]=2*(num[1]-1)+1;//考虑顺序 for(int i=2;i<=n;i++) { if(num[i]==1) dp2[i]=dp1[i]%m; else dp2[i]=(2*dp1[i-1]+2*num[i]+dp2[i-1])%m; } printf("%d\n",dp2[n]); } return 0;}
- POj 3601 Tower of Hanoi 汉诺塔(贪心)
- poj 3601 Tower of Hanoi
- POJ 3601:Tower of Hanoi
- POJ 3601 Tower of Hanoi
- Tower of Hanoi(汉诺塔)
- [poj 3601]Tower of Hanoi 数论
- 汉诺塔 Tower of Hanoi
- pku 3601 Tower of Hanoi
- 汉诺塔(the Tower of Hanoi )
- 汉诺塔(Hanoi Tower)
- codeforces 392 B. Tower of Hanoi(汉诺塔 DP)
- python 汉诺塔问题(Tower of Hanoi Puzzle)
- THE TOWER OF HANOI
- Tower of Hanoi
- Tower of Hanoi
- Tower of Hanoi
- Tower of Hanoi问题
- codeforces Tower of Hanoi
- C++虚函数的原理及实现
- MSDN: WDM与KMDF的区别
- ^ shell
- 130821创建索引
- MDI窗体的优化---上
- POj 3601 Tower of Hanoi 汉诺塔(贪心)
- oracle 锁粒度
- Hoj 1917 Peaceful Commission
- HTML5_Canvas_属性、定义及方法
- ETL错误
- C++书籍
- 编程原则
- struts2常见错误总结
- 黑马程序员-------关于里氏替换原则、类型转换