SGU 202 The Towers of Hanoi Revisited (DP+递归)

来源:互联网 发布:ubuntu 杀死所有进程 编辑:程序博客网 时间:2024/06/07 16:42

转载请注明出处,谢谢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());    }}



原创粉丝点击