SGU 202 The Towers of Hanoi Revisited (DFS+预处理)

题目描述:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2338

The Towers of Hanoi Revisited


Time Limit: 5 Seconds     
Memory Limit: 32768 KB      Special Judge



You all must know the puzzle named ??The Towers of Hanoi??. The puzzle has three pegs and N discsof different radii, initially all disks are located on the first peg, ordered by their radii - the largest atthe bottom, the smallest at the top. In a turn you
may take the topmost disc from any peg and move itto another peg, the only rule says that you may not place the disc atop any smaller disk. The problemis to move all disks to the last peg making the smallest possible number of moves.

There is the legend that somewhere in Tibet there is a monastery where monks tirelessly move disksfrom peg to peg solving the puzzle for 64 discs. The legend says that when they finish, the end of theworld would come. Since it is well known that to solve
the puzzle you need to make 2N - 1 moves, asmall calculation shows that the world seems to be a quite safe place for a while.

However, recent archeologists discoveries have shown that the things can be a bit worse. Themanuscript found in Tibet mountains says that the puzzle the monks are solving has not 3 but Mpegs. This is the problem, because when increasing the number of pegs,
the number of moves needed tomove all discs from the first peg to the last one following the rules described, decreases dramatically.Calculate how many moves one needs to move N discs from the first peg to the last one when thepuzzle has M pegs and provide
the scenario for moving the discs.

This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

Input

Input file contains N and M (1 <= N <= 64, 4 <= M <= 65).

Output

On the first line output L - the number of moves needed to solve the puzzle. Next L lines mustcontain the moves themselves. For each move print the line of the form

move <disc-radius> from <source-peg> to <target-peg>

if the disc is moved to the empty peg or

move <disc-radius> from <source-peg> to <target-peg> atop <target-top-disc-radius>

if the disc is moved atop some other disc.

Disc radii are integer numbers from 1 to N, pegs are numbered from 1 to M.

Sample Input

1

5 4

Sample Output

13

move 1 from 1 to 3

move 2 from 1 to 2

move 1 from 3 to 2 atop 2

move 3 from 1 to 4

move 4 from 1 to 3

move 3 from 4 to 3 atop 4

move 5 from 1 to 4

move 3 from 3 to 1

move 4 from 3 to 4 atop 5

move 3 from 1 to 4 atop 4

move 1 from 2 to 1

move 2 from 2 to 4 atop 3

move 1 from 1 to 4 atop 2

题目大意:

  给定N(1<= N <=64)个盘子和M(4<= M <= 65)根柱子,问把N个盘子从1号柱子移动到M号柱子所需要的最少步数,并且输出移动过程。

解题思路:

  对于整个移动的过程可以概括为如下:

先把k个盘子,通过j跟柱子移动到中间的某根柱子上,步数:f[k][j];

把剩下的i-k个盘子通过剩下的j-1跟柱子移到第j跟柱上,步数:f[i-k][j-1];

最后再把中间的k个盘子移到J柱上,步数:f[k][j]。

  为防止重复计算,且该题状态有限(64*65),因此作为预处理将所有的状态所需最小步数求出。
再通过DFS按照上述思路打印出移动步骤即可。

复杂度分析:

时间复杂度 O(n*n)

空间复杂度 O(n*n)

#include <cstdio>
#include <stack>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 70;
const unsigned long long INF=0xffffffffffffffff;///定义无限大
unsigned long long f[maxn][maxn]; ///f[i][j]表示i个盘,通过j个柱子,全程移动所需要的最少次数。
int pre[maxn][maxn]; ///pre[i][j]表示f[i][j]的最优方案是先将最小的path[i][j]个盘移动到中间某根的柱子上
int n,m;///n个盘子 m个柱子
stack<int>stk[maxn];
bool used[maxn];
void init()
{
   memset(f,INF,sizeof(f));
   for(int i=3;i<=65;i++)
   {
       f[0][i]=0;
       f[1][i]=1;
   }
   for(int i=1;i<=64;i++)
   {
       f[i][3]=2*f[i-1][3]+1;
       pre[i][3]=i-1;
   }
   for(int i=2;i<=64;i++)
    for(int j=4;j<=65;j++)
     for(int k=1;k<i;k++)
     {
       if(f[i][j]>2*f[k][j]+f[i-k][j-1])
       {
           f[i][j]=2*f[k][j]+f[i-k][j-1];
           pre[i][j]=k;
       }
    }
}
void dfs(int nt,int mt,int scr,int des)
{
   if(nt==1)
   {
       if(stk[des].size())
         printf("move %d from %d to %d atop %d\n",stk[scr].top(),scr,des,stk[des].top());
       else
         printf("move %d from %d to %d\n",stk[scr].top(),scr,des);
       stk[des].push(stk[scr].top());
       stk[scr].pop();
       return;
   }
   int peg=0;
   for(int i=1;i<=m;i++)
   {
       if(scr!=i && des!=i && !used[i])
       {
           peg=i;
           break;
       }
   }
   dfs(pre[nt][mt],mt,scr,peg);
   used[peg]=true;
   dfs(nt-pre[nt][mt],mt-1,scr,des);
   used[peg]=false;
   dfs(pre[nt][mt],mt,peg,des);
}
int main()
{
   init();
   int N;
   cin>>N;
   while(N--)
   {
       cin>>n>>m;
       for(int i=1;i<=m;i++) while(!stk[i].empty()) stk[i].pop();
       for(int i=n;i>=1;i--) stk[1].push(i);
       memset(used,false,sizeof(used));
       printf("%llu\n",f[n][m]);
       dfs(n,m,1,m);
   }
   return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-04 00:35:23

SGU 202 The Towers of Hanoi Revisited (DFS+预处理)的相关文章

Acdream 1219 The Towers of Hanoi Revisited(递归汉诺塔问题)

传送门 The Towers of Hanoi Revisited Special Judge Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description You all must know the puzzle named "The Towers of Hanoi". The puzz

zoj 2338 The Towers of Hanoi Revisited

1 #include<iostream> 2 #include<algorithm> 3 #include<stack> 4 using namespace std; 5 stack<int> a[3]; 6 int b[60]; 7 int q=0; 8 int solve(int from,int to) 9 { 10 if(a[from].empty()) 11 {//-1有错 12 return -1; 13 } 14 if(!a[to].empty

URAL 2029 Towers of Hanoi Strike Back 汉诺塔,从初始状态到任意给出状态需要的次数

F - Towers of Hanoi Strike Back Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 2029 Description The Tower of Hanoi puzzle was invented by French mathematician édouard Lucas in the second half

POJ 1958 Strange Towers of Hanoi (线性dp,记忆化搜索)

JQuery工具方法. (1)$.isNumeric(obj) 此方法判断传入的对象是否是一个数字或者可以转换为数字. isNumeric: function( obj ) { // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...&

POJ 1920 Towers of Hanoi

OJ题目:click here~~ 题目分析:三根柱子 , n个圆盘 .给一个汉诺塔的状态,求将所有盘挪到一个柱子上的最少步数,并给出是最后在哪个柱子上. 从给定状态到目标状态很复杂,但是从目标状态到给定的状态就很容易想了.将一个柱子上i个盘,挪到另一个柱子上,需要pow(2,i) - 1步. 显然,最后在的那个柱子,一定是所给状态下最大盘所在的柱子.接下来考虑第二大的盘,需要移动就移动.--详见代码注释. AC_CODE const int mod = 1000000; int p[10000

poj 1958 Strange Towers of Hanoi

Strange Towers of Hanoi Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 2678   Accepted: 1742 Description Background Charlie Darkbrown sits in another one of those boring Computer Science lessons: At the moment the teacher just explains

POJ 1958 Strange Towers of Hanoi (四塔问题,线性dp,记忆化搜索)

题目分析:四柱汉诺塔.由于题目已经给出了求解方法,直接写代码即可.下面总结一下,四塔问题. 感谢这篇文章的作者,点这里就到,总结的很好.直接贴过来~ 四塔问题:设有A,B,C,D四个柱子(有时称塔),在A柱上有由小到大堆放的n个盘子. 今将A柱上的盘子移动到D柱上去.可以利用B,C柱作为工作栈用,移动的规则如下: ①每次只能移动一个盘子. ②在移动的过程中,小盘子只能放到大盘子的上面. 设计并实现一个求解四塔问题的动态规划算法,并分析时间和空间复杂性. 算法思想: 用如下算法移动盘子(记为Fou

The Towers of Hanoi Revisited---(多柱汉诺塔)

Description You all must know the puzzle named "The Towers of Hanoi". The puzzle has three pegs and N discs of different radii, initially all disks are located on the first peg, ordered by their radii - the largest at the bottom, the smallest at

[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 which can slide onto any tower. The puzzle starts with disks sorted in ascending order of size from top to bottom (i.e., each disk sits on top of an e