Tower of Hanoi
Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 1895   Accepted: 646

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 a1a2, …, an (1 ≤ a1a2, …, 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

 
从别人的博客学习的

解题报告:
假设有n种盘子,x[i]为第i种盘子的数目, 0 <= i <= n - 1.
我们先计算出相同的盘子不考虑顺寻的情况,记作a[i],表示有i种盘子所需的步骤数目(不考虑第i种顺序)。
容易知道,a[0] = x[0],只有一种时,直接把这种的所有盘子移动到目标轴上。
a[i] = 2 * a[i - 1] x[i].
说明:如果从A到C轴,借助B轴,i种盘子,要先把i - 1种移动到 B, 需要a[i - 1],然后把第i种移动到C,需要x[i],然后再把i - 1种从B移动到C,需要a[i - 1]
所以得到a[i] = 2 * a[i - 1] x[i].

但是题目是需要考虑相同盘子的顺序的,这里记作b[i],为移动i种盘子考虑顺序需要的步骤。
b[0] = 2 * (x[0] - 1) 1.
说明:把x[0] - 1个移动到辅助轴,这时这x[0] - 1个盘子的顺序颠倒了,然后把第x[0]中最后一个移动到目标轴,然后把辅助轴上的移动回来,再次颠倒,恢复顺序,得到b[0] = 2 * (x[0] - 1) 1。
对于b[i],
如果x[i] == 1,那么第i种就不需要考虑顺序(只有一种),所以b[i] = a[i]
否则,第i种要调动2次,保证顺序不变。
还是从A到C轴,借助B轴,i种盘子
把i - 1种不考虑顺序移到C,需要a[i - 1].
把第i种从A移动到B,需要x[i](颠倒顺序),
把i - 1种不考虑顺序移到A(腾出C),需要a[i - 1].
把第i种从B移动到C,需要x[i](顺序恢复)
把i - 1种考虑顺序移到C,需要b[i - 1].
所以有b[i] = 2 * a[i - 1] 2 * x[i] b[i - 1]
最后答案是b[n - 1].

题意:Hanoi塔问题,只不过有一些盘子的大小是一样的,所有的盘子转移到另一个塔,相同大小的盘子要保证原本的顺序不变,问你最少的步骤数目,结果对m取余。

输入n,m,n表示有几种盘子大小,m表示结果将要取余的数。

第二行输入n个数,表示盘子从小到大每种盘子大小的个数。如{1,3,2}表示大小为1的盘子有1个,大小为2的盘子有3个,大小为3的盘子有2个。

附上代码:

 #include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int i,j,n,m,a[],b[],x[];
while(~scanf("%d%d",&n,&m))
{
for(i=; i<n; i++)
scanf("%d",&x[i]);
a[]=x[];
for(i=; i<n; i++)
a[i]=(a[i-]*+x[i])%m;
b[]=*x[]-;
for(i=; i<n; i++)
{
if(x[i]==)
b[i]=a[i];
else
b[i]=(*a[i-]+*x[i]+b[i-])%m;
}
printf("%d\n",b[n-]);
}
return ;
}

poj 3601Tower of Hanoi的更多相关文章

  1. poj 3601 Tower of Hanoi

    Tower of Hanoi Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 1853   Accepted: 635 De ...

  2. 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 ...

  3. POJ 1958 Strange Towers of Hanoi

    Strange Towers of Hanoi Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3784 Accepted: 23 ...

  4. 【POJ 1958】 Strange Towers of Hanoi

    [题目链接] http://poj.org/problem?id=1958 [算法] 先考虑三个塔的情况,g[i]表示在三塔情况下的移动步数,则g[i] = g[i-1] * 2 + 1 再考虑四个塔 ...

  5. poj 3572 Hanoi Tower

    Hanoi Towers Time Limit : 10000/5000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total ...

  6. poj 1920 Towers of Hanoi

    Towers of Hanoi Time Limit: 3000MS   Memory Limit: 16000K Total Submissions: 2213   Accepted: 986 Ca ...

  7. Strange Towers of Hanoi POJ - 1958(递推)

    题意:就是让你求出4个塔的汉诺塔的最小移动步数,(1 <= n <= 12) 那么我们知道3个塔的汉诺塔问题的解为:d[n] = 2*d[n-1] + 1 ,可以解释为把n-1个圆盘移动到 ...

  8. POJ 题目分类(转载)

    Log 2016-3-21 网上找的POJ分类,来源已经不清楚了.百度能百度到一大把.贴一份在博客上,鞭策自己刷题,不能偷懒!! 初期: 一.基本算法: (1)枚举. (poj1753,poj2965 ...

  9. (转)POJ题目分类

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

随机推荐

  1. 函数的length属性

       函数的length 属性指明函数的形参个数.   length 是函数对象的一个属性值,指该函数有多少个必须要传入的参数,即形参的个数.形参的数量不包括剩余参数个数,仅包括第一个具有默认值之前的 ...

  2. 第十章—DOM(二)——Element类型

    Element类型用于表现HTML和XML,提供了对元素标签名,子节点和特效的访问.Element节点具有以下特征: 要访问元素的标签名,可以使用nodeName属性,也可以使用tagName属性.这 ...

  3. .Net Core 授权系统组件解析

    前面关于.Net Core如何进行用户认证的核心流程介绍完毕之后,.Net Core 认证系统之Cookie认证源码解析远程认证暂时不介绍,后期有时间,我会加上.接下去介绍认证组件是如何和认证组件一起 ...

  4. 【JZOJ4461】【GDOI2016模拟4.21】灯塔 分治

    题面 GDOI是一个地处丘陵的小国,为了边防建设,国王希望在国界线上的某一座山峰上建立一座灯塔,照亮整个边界.而灯塔建设的调研工作,就交给了你. GDOI的国境线上有N座连续的山峰,其中第i座的高度是 ...

  5. python基础知识--标志位的设定

    在单层循环的退出中,使用break即能退出,那么多层循环呢?机智的人们使用flag标识符的方式,例如: exit_flag = False for i in range(10): if i <5 ...

  6. vue-cli3 关闭eslint

    关闭eslint 直接注释掉package.json文件中eslint的配置就可以了(以下是vue-cli的默认配置) "eslintConfig": { "root&q ...

  7. 【JZOJ4930】【NOIP2017提高组模拟12.18】C

    题目描述 给出一个H的行和W列的网格.第i行第j列的状态是由一个字母的A[i][j]表示,如下: "." 此格为空. "o" 此格包含一个机器人. " ...

  8. 【JZOJ4910】【NOIP2017模拟12.3】子串

    题目描述 数据范围 =w= 暴力: 从前往后枚举一个i,再从前往后枚举一个j: 如果s[i]不是s[j]的子串,更新答案,继续枚举: 如果s[i]是s[j]的子串,停止枚举. 因为对于s[k] (k& ...

  9. 解决Dynamic Web Module 3.0 requires Java 1.6 or newer.问题

    在项目的pom.xml的<build></build>标签中增加: <plugins>       <plugin>           <gro ...

  10. Effective Modern C++:05右值引用、移动语义和完美转发

    移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作:完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参.右值引 ...