SGU 202 The Towers of Hanoi Revisited (DFS+预处理)
来源:互联网 发布:购买软件源代码协议 编辑:程序博客网 时间:2024/05/15 03:37
题目描述:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2338
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
if the disc is moved to the empty peg or
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
15 4
Sample Output
13move 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;}
- SGU 202 The Towers of Hanoi Revisited (DFS+预处理)
- sgu-202 The Towers of Hanoi Revisited
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
- ZOJ Problem Set - 2338 The Towers of Hanoi Revisited DFS+预处理
- zoj 2338 The Towers of Hanoi Revisited
- ACdream 1219 The Towers of Hanoi Revisited多柱汉诺塔【递归】
- Acdream 1219 The Towers of Hanoi Revisited(递归汉诺塔问题)
- UVa10017 - The Never Ending Towers of Hanoi(dfs)
- The Towers of Hanoi recursion 汉诺塔 C++
- 汉诺塔(Towers of Hanoi)问题
- uva 254 - Towers of Hanoi(递归)
- poj1920 Towers of Hanoi
- poj1958Strange Towers of Hanoi
- UVa Problem 10017 - The Never Ending Towers of Hanoi
- UVa Problem 10017 - The Never Ending Towers of Hanoi
- UVa 10017 - The Never Ending Towers of Hanoi
- JOJ-2033-Towers of Hanoi
- poj 1920 Towers of Hanoi
- GCC 的详细使用
- Mysql创建表格
- Sliding Window Maximum
- python实现栈和队列
- A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run STS
- SGU 202 The Towers of Hanoi Revisited (DFS+预处理)
- PHP opencart 框架后台管理二次开发流程说明
- android-----上传文件到服务器
- 电信行业大数据应用的四个方向
- pdfFactory Pro 不能被安装(AddPrinterDriver 失败)...找不到指定的模块
- Thread:智能家庭无线mesh网络新标准
- 我这三年
- ARM中的RO、RW和ZI DATA说明
- C/C++笔记(一) 2015/8/15