ZOJ Problem Set - 2338 The Towers of Hanoi Revisited DFS+预处理
来源:互联网 发布:磁卡刷卡器软件 编辑:程序博客网 时间:2024/05/29 08:07
ZOJ Problem Set - 2338 The Towers of Hanoi Revisited
题目描述:
题目链接:Problem Set - 2338 The Towers of Hanoi Revisited
题目大意:
给定
解题思路:
对于整个移动的过程可以概括为如下:
先把
k 个盘子,通过j跟柱子移动到中间的某根柱子上,步数:f[k][j] ;把剩下的
i−k 个盘子通过剩下的j−1 跟柱子移到第j跟柱上,步数:f[i−k][j−1] ;最后再把中间的
k 个盘子移到J柱上,步数:f[k][j] 。为防止重复计算,且该题状态有限
(64∗65) ,因此作为预处理将所有的状态所需最小步数求出。
再通过DFS 按照上述思路打印出移动步骤即可。
复杂度分析:
时间复杂度
空间复杂度
AC代码:
#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; }//所有盘数为0的情况,步数为0.所有盘数为1的情况,步数为1 for(int i = 1; i <= 64; i++){ f[i][3] = f[i-1][3] * 2 + 1; pre[i][3] = i - 1; }//初始化三根柱子的情况 for(int i = 2; i <= 64; i++){//盘数从2起 for(int j = 4; j <= 65; j++){ //柱数从3起 for(int k = 1; k < i; k++){//为达到最优方案处于中间柱上的盘数。 if(f[i][j] > f[i-k][j-1] + 2*f[k][j]){ f[i][j] = f[i-k][j-1] + 2*f[k][j]; pre[i][j] = k; } /*先把k个盘子,通过j跟柱子移动到中间的某根柱子上f[k][j]; 把剩下的i-k个盘子通过剩下的j-1跟柱子移到第j跟柱子f[i-k][j-1]; 最后再把中间的k个盘子移到J柱上f[k][j]。 共计f[i-k][j-1] + 2*f[k][j]*/ } } }}void dfs(int nt,int mt,int src,int des){//nt盘数,mt柱数,src起点,des终点 if(nt == 1){ if(stk[des].size()) printf("move %d from %d to %d atop %d\n",stk[src].top(),src,des,stk[des].top()); else printf("move %d from %d to %d\n",stk[src].top(),src,des); stk[des].push(stk[src].top()); stk[src].pop(); return; } int peg = 0; //柱子编号 for(int i = 1; i <= m; i++){ if(i != src && i != des && !used[i] ){ peg = i; break; } } dfs(pre[nt][mt],mt,src,peg);//先把k个盘子,通过j跟柱子移动到中间的某根柱子上 used[peg] = true; dfs(nt - pre[nt][mt],mt-1,src,des);//把剩下的i-k个盘子通过剩下的j-1跟柱子移到第j跟柱子 used[peg] = false; dfs(pre[nt][mt],mt,peg,des);//最后再把中间的k个盘子移到J柱上}int main(){ init(); int N; cin >> N; while(N--){ scanf("%d%d",& 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;}
0 0
- ZOJ Problem Set - 2338 The Towers of Hanoi Revisited DFS+预处理
- zoj 2338 The Towers of Hanoi Revisited
- SGU 202 The Towers of Hanoi Revisited (DFS+预处理)
- sgu-202 The Towers of Hanoi Revisited
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
- ACdream 1219 The Towers of Hanoi Revisited多柱汉诺塔【递归】
- Acdream 1219 The Towers of Hanoi Revisited(递归汉诺塔问题)
- UVa10017 - The Never Ending Towers of Hanoi(dfs)
- UVa Problem 10017 - The Never Ending Towers of Hanoi
- UVa Problem 10017 - The Never Ending Towers of Hanoi
- The Towers of Hanoi recursion 汉诺塔 C++
- poj1920 Towers of Hanoi
- poj1958Strange Towers of Hanoi
- 汉诺塔迭代算法(Towers of Hanoi, classic problem (recursive method))
- ZOJ Problem Set - 2818 Root of the Problem
- UVa 10017 - The Never Ending Towers of Hanoi
- JOJ-2033-Towers of Hanoi
- poj 1920 Towers of Hanoi
- 【学习笔记】Linux的命令总结(三)
- Asp.mvc(三) ~ 使用 Autofac 实现依赖注入
- 再谈java事件监听机制
- ZOJ Problem Set - 1649 Rescue BFS+优先队列
- Java基础教程之事件和监听器
- ZOJ Problem Set - 2338 The Towers of Hanoi Revisited DFS+预处理
- 深入理解JAVA事件机制
- hadoop2.x学习01
- DBCP数据库连接池
- ZOJ Problem Set - 3429 Cube Simulation
- JAVA监听器原理
- 【学习笔记】mysql 快速批量导入测试数据
- POJ 1836 Alignment 双向LIS+DP
- Problem M. Heaviside Functionz