poj 3601 Tower of Hanoi
Time Limit: 1000MS | Memory Limit: 131072K | |
Total Submissions: 1853 | Accepted: 635 |
Description
The Tower of Hanoi is a puzzle consisting of three pegs and a number of disks of different sizes which can slide onto any peg. The puzzle starts with the disks neatly stacked in order of size on one peg, the smallest at the top, thus making a conical shape. The objective of the puzzle is to move the entire stack to another peg, obeying the following rules:
- Only one disk may be moved at a time.
- Each move consists of taking the upper disk from one of the pegs and sliding it onto another peg, on top of the other disks that may already be present on that peg.
- No disk may be placed on top of a smaller disk.
For n disks, it is a well-known result that the optimal solution takes 2n − 1 moves.
To complicate the puzzle a little, we allow multiple disks to be of the same size. Moreover, equisized disks are mutually distinguishable. Their ordering at the beginning should be preserved at the end, though it may be disturbed during the process of solving the puzzle.
Given the number of disks of each size, compute the number of moves that the optimal solution takes.
Input
The input contains multiple test cases. Each test case consists of two lines. The first line contains two integers n and m (1 ≤ n ≤ 100, 1 ≤ m ≤ 106). The second lines contains n integers a1, a2, …, an (1 ≤ a1, a2, …, an ≤ 105). For each 1 ≤ i ≤ n, there are ai disks of size i. The input ends where EOF is met.
Output
For each test case, print the answer modulo m on a separate line.
Sample Input
1 1000
2
5 1000
1 1 1 1 1
5 1000
2 2 2 2 2
5 1000
1 2 1 2 1
Sample Output
3
31
123
41
Source
分析:
学习网址:http://blog.csdn.net/acm18810549519/article/details/10155281
动态规划
题意:汉诺塔问题,不过其中加了一个条件,就是盘子可以有相同的
可以发现,当移动第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].
//起始条件:dp1[1]=num[1];dp2[1]=2*num[1]-1
//num[i]==1:dp2[i]=2*dp1[i-1]+1
//num[i]>=2:dp2[i]=dp1[i]+num[i]+dp1[i]+num[i]+dp2[i]=2*dp1[i-1]+2*num[i]+dp2[i-1]
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
int num[],dp1[],dp2[];
int main(){
int n,m;
while(cin>>n>>m){
int i=;
for(;i<=n;i++){
cin>>num[i];
}
dp1[]=num[]%m;
dp2[]=(*(num[]-)+)%m;
for(i=;i<=n;i++){
dp1[i]=(*dp1[i-]+num[i])%m;
if(num[i]==){
dp2[i]=dp1[i];
}
else{
dp2[i]=(*dp1[i-]+*num[i]+dp2[i-])%m;
}
}
cout<<dp2[n]<<endl;
}
return ;
}
poj 3601 Tower of Hanoi的更多相关文章
- 尺取法 POJ 3601 Subsequence
题目传送门 /* 题意:求连续子序列的和不小于s的长度的最小值 尺取法:对数组保存一组下标(起点,终点),使用两端点得到答案 1. 记录前i项的总和,求[i, p)长度的最小值,用二分找到sum[p] ...
- python递归三战:Sierpinski Triangle、Tower of Hanoi、Maze Exploring
本文已做成视频教程投稿b站(视频版相对文本版有一些改进),点击观看视频教程 本文主要通过三个实例来帮助大家理解递归(其展示动画已上传B站): 谢尔宾斯基三角形(Sierpinski Triangle) ...
- 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法
非递归算法: 根据圆盘的数量确定柱子的排放顺序: 若n为偶数,按顺时针方向依次摆放 A B C: 若n为奇数,按顺时针方向依次摆放 A C B. 然后进行如下操作: (1)按顺时针方向把圆盘1从现在的 ...
- poj 1920 Towers of Hanoi
Towers of Hanoi Time Limit: 3000MS Memory Limit: 16000K Total Submissions: 2213 Accepted: 986 Ca ...
- Tower of Hanoi问题
[问题描述] 有A, B, C三个塔座,A上套有n个直径不同的圆 盘,按直径从小到大叠放,形如宝塔,编号1, 2, 3 … n. 要求将n个圆盘从A移到C,叠放顺序不变,移动过程中遵循 下列原则: w ...
- [POJ1958][Strange Tower of Hanoi]
题目描述 求解 \(n\) 个盘子 \(4\) 座塔的 Hanoi 问题最少需要多少步 问题分析 考虑 \(3\) 座塔的 Hanoi 问题,记 \(f[i]\) 表示最少需要多少步, 则 \(f[i ...
- One usage of recurison: the tower of Hanoi
Statements: This blog was written by me, but most of content is quoted from book[Data Structure wit ...
- 汉诺塔 Tower of Hanoi
假设柱子标为A,B.C.要由A搬至C,在仅仅有一个盘子时,就将它直接搬至C:当有两个盘子,就将B作为辅助柱.假设盘数超过2个.将第二个下面的盘子遮起来,就非常easy了.每次处理两个盘子,也就是:A- ...
- codeforces 392B Tower of Hanoi
把前n个碟子从第一个塔移动到第三个塔有两种方法: 1.把前n-1个移动到第二个塔,把第n个移动到第三个塔,然后把前n-1个从第二个移动到第三个: 2.把前n-1个移动到第三个塔,把第n个移动到第二个塔 ...
随机推荐
- Android-隐式意图激活所有应用
显示意图 与 隐式意图 对比 显示意图不能激活多个组件,只能激活一个组件 隐式意图能激活多个组件 显示意图只能在自身应用激活,不能激活其他应用 隐士意图能在自身应用激活,也能激活其他应用 每个应用程序 ...
- Linux Guard Service - 守护进程的作用、用途、父进程标识的特点
让test2直接成为守护进程 [root@localhost 02]# cat test2.c //test2 #include<stdio.h> #include<unistd.h ...
- Ray tracing performance benchmark
accel. avg size 3.14accel. avg depth 16.15accel. max size 8accel. max depth 20accel. GPIT 3.00 MB tr ...
- mvn install 报错Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2 错误: 找不到符号
报错信息 在Eclipse中执行mvn install时,console端显示如下报错信息: [ERROR] Failed to execute goal org.apache.maven.plugi ...
- vim 在 cmdline 内粘贴的方法
vim 在 cmdline 内粘贴的方法: 先按下 Ctrl-r ,然后选择从哪个剪贴板上粘贴 0 (yank register), 1 to 9 (shifting delete registers ...
- navicat 导入txt到数据库
一直都是建库 一条条添加数据 昨天碰上要导入一堆数据突然不知所措 查资料才弄好,先记录一下,以免忘记 这个是导入的数据名可以改 对导入数据表进行增删改 以上!
- THUSC2017酱油记
啊..酱油记三连发.. 果然SHTSC用掉太多RP了.. 其实感觉没什么好写的..都被考懵逼了.. 但还是写一下吧.. DAY0 月考完提前一天到了..什么也没发生 DAY1 先考试再开幕式..好奇怪 ...
- [Flex] 组件Tree系列 —— 实现右键拓展功能
主程序mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述:结合tree拓展右键功能 必 ...
- ArchLinux中证书错误解决方案
ca-certificates 更新 x509: failed to load system roots and no roots provided. curl error: Problem with ...
- Ping程序
一.概述 Ping程序是对两个TCP/IP系统连通性进行测试的基本工具.该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答. 二.格式 大多数TCP/IP实现都在内核中直接支持Pin ...