zoj 2338 The Towers of Hanoi Revisited
来源:互联网 发布:淘宝客买家平台 编辑:程序博客网 时间:2024/05/29 09:30
还是太naive了,在知道经典汉诺塔的情况下,居然很久没想出来。其实多根棍子和三根是一个原理。n个盘子,m根棍子的最优解,一定是把一部分盘子(假设为x)先移到某个中间棍子上,也就是先解决子问题(x,m),然后把剩下的n-x个盘子通过剩下的m-1根棍子用最优方案转移,即子问题(n-x,m-1),最后把中间棍子上的那x个盘子移过去,即子问题(x,m)。这样可以用dp来求解。
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <string> #include <memory.h> #include <vector> #include <queue> #include <stack> using namespace std;#define ll unsigned long long ll dp[77][77];int num[77][77];ll fun(int n,int m){ if(dp[n][m]){ return dp[n][m]; } if(n==0){ return 0; }else if(n==1){ return 1; }else if(m==2){ return n; }else if(m==3){ num[n][m] = n-1; dp[n][m] = fun(n-1,3)*2+1; return dp[n][m]; } ll res = (~(0ULL))>>1;; for(int i=1;i<n;i++){ ll tmp = fun(i,m)*2+fun(n-i,m-1); if(tmp<=res){ res = tmp; num[n][m] = i; } } dp[n][m] = res; return res;}stack<int> pegs[77];void move(int from,int to){ if(pegs[to].size()){ printf("move %d from %d to %d atop %d\n",pegs[from].top(),from,to,pegs[to].top()); pegs[to].push( pegs[from].top() ); pegs[from].pop(); }else{ printf("move %d from %d to %d\n",pegs[from].top(),from,to); pegs[to].push( pegs[from].top() ); pegs[from].pop(); }}int M;void solve(int n,int m,int from,int to){ if(n==1){ move(from,to); return; } if(m==2){ while(n--){ move(from,to); } return; } stack<int> where; stack<int> how; int curn = n; int curm = m; for(int i=1;i<=M;i++){ if(i==from || i==to)continue; if(pegs[i].size() && pegs[from].top()>pegs[i].top())continue; int tmp = num[curn][curm]; if(tmp==0){ break; } if(curn==1)break; solve(tmp,curm,from,i); where.push(i); how.push(tmp); curn-=tmp; curm--; } curm++; move(from,to); while(where.size()){ solve(how.top(),curm,where.top(),to); how.pop(); where.pop(); curm++; }}int main(){ for(int i=1;i<=65;i++){ for(int j=4;j<=65;j++){ fun(i,j); } } int t; cin>>t; while(t--){ int n,m; cin>>n>>m; M = m; for(int i=n;i>=1;i--){ pegs[1].push(i); } cout<<fun(n,m)<<endl; solve(n,m,1,m); while(pegs[m].size()){ pegs[m].pop(); } } return 0;}
0 0
- zoj 2338 The Towers of Hanoi Revisited
- ZOJ Problem Set - 2338 The Towers of Hanoi Revisited DFS+预处理
- sgu-202 The Towers of Hanoi Revisited
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
- SGU 202 The Towers of Hanoi Revisited (DFS+预处理)
- ACdream 1219 The Towers of Hanoi Revisited多柱汉诺塔【递归】
- Acdream 1219 The Towers of Hanoi Revisited(递归汉诺塔问题)
- The Towers of Hanoi recursion 汉诺塔 C++
- 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
- UVa10017 - The Never Ending Towers of Hanoi(dfs)
- UVa 10017 - The Never Ending Towers of Hanoi
- JOJ-2033-Towers of Hanoi
- poj 1920 Towers of Hanoi
- poj 1920 Towers of Hanoi
- UVa:254 Towers of Hanoi
- 网页中在线客服关联QQ
- Matlab&Simulink开发STM32F4
- OBJ-C简介部分学习笔记
- Leetcode 343. Integer Break
- hdu_5667_sequence
- zoj 2338 The Towers of Hanoi Revisited
- Hive JSON数据处理的一点探索
- 学习
- 哈理工OJ 1189 区间最大值 II(线段树【简单】)
- brctl工具学习
- R语言前期准备之LINUX下安装
- 时间的输出
- typeof
- <转>HttpClient和HttpURLConnection的区别