SGU 202 The Towers of Hanoi Revisited (DP+遞迴)
轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
題意 :n個圓盤,m個柱子的漢諾塔輸出步驟。
http://acm.sgu.ru/problem.php?contest=0&problem=202
經典的遞迴問題,見具體數學第一章
先DP求出最短步驟,並記錄路徑。
然後 遞迴輸出。
import java.util.*;
import java.io.*;
import java.math.*;
public class Solution {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Task solver = new Task();
solver.solve(in, out);
out.close();
}
}
class Task{
static int dp [][] = new int [70][70];
static int pre[][] = new int [70][70];
static int inf = 100000009;
static int N,M;
Stack s[] = new Stack [70];
int dfs(int n,int m){
if(dp[n][m]!=-1)
return dp[n][m];
dp[n][m]=inf;
for(int i=1;i<n;i++){
int t=dfs(i,m)*2+dfs(n-i,m-1);
if(t<dp[n][m]){
dp[n][m]=t;
pre[n][m]=i;
}
}
return dp[n][m];
}
void move(int u,int v){
System.out.print("move " + s[u].peek() + " from " + u + " to " + v);
if(!s[v].empty())
System.out.print(" atop " + s[v].peek());
s[v].push(s[u].pop());
System.out.println();
}
void gao(int u,int v,int n,int m){
if(n==1){
move(u,v);
return ;
}
if(s[u].size()<pre[n][m]) return ;
for(int mid=1;mid<=M;mid++){
if(mid==u||mid==v) continue;
if(s[mid].empty()||((int)(s[mid].peek())>(int)(s[u].elementAt(s[u].size()-pre[n][m])))){
gao(u,mid,pre[n][m],m);
gao(u,v,n-pre[n][m],m-1);
gao(mid,v,pre[n][m],m);
return ;
}
}
}
void solve(InputReader in,PrintWriter out){
N=in.nextInt();M=in.nextInt();
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
dp[i][j]=-1;
for(int i=1;i<=N;i++)
dp[i][1]=dp[i][2]=inf;
dp[1][1]=0;
for(int i=2;i<=M;i++)
dp[1][i]=1;
dfs(N,M);
System.out.println(dp[N][M]);
for(int i=1;i<=M;i++)
s[i]=new Stack();
for(int i=N;i>=1;i--)
s[1].push(i);
gao(1,M,N,M);
}
}
class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream));
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
相關文章
- Towers of Hanoi題解
- POJ 3572 Hanoi Towers (YY + 推公式)公式
- HT for Web 3D遊戲設計設計--漢諾塔(Towers of Hanoi)Web3D遊戲設計
- 遞迴和尾遞迴遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- 遞迴遞迴
- SGU 505
- ACM(遞迴遞推—A)ACM遞迴
- ACM(遞迴遞推—I)ACM遞迴
- JavaScript遞迴JavaScript遞迴
- go 遞迴Go遞迴
- 理解遞迴遞迴
- 遞迴 Java遞迴Java
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 遞迴和遞推總結遞迴
- 演算法小專欄:遞迴與尾遞迴演算法遞迴
- 迭代與遞迴--你被遞迴搞暈過嗎?遞迴
- SGU 120 SGU 228 Archipelago(計算幾何)Go
- 遞迴函式遞迴函式
- 理解遞迴 Recurtion遞迴
- 遞迴-*快速排序遞迴排序
- sql server遞迴SQLServer遞迴
- C#遞迴C#遞迴
- Vue元件遞迴Vue元件遞迴
- javascript遞迴整理JavaScript遞迴
- oracle遞迴(二)Oracle遞迴
- oracle遞迴(一)Oracle遞迴
- SQL 遞迴思想SQL遞迴
- 快速排序(遞迴及非遞迴演算法原始碼)排序遞迴演算法原始碼
- ?30 秒瞭解尾遞迴和尾遞迴優化遞迴優化
- 徹底理解遞迴,從遞迴的本質說起!遞迴
- 【C++】翻轉二叉樹(遞迴、非遞迴)C++二叉樹遞迴
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- Vue3.0的遞迴監聽和非遞迴監聽Vue遞迴
- PostgreSQL 遞迴查詢SQL遞迴
- model 遞迴子級遞迴
- 函式的遞迴函式遞迴
- Oracle和Mysql遞迴OracleMySql遞迴