• 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());
        }
    }



  • 相关阅读:
    Vue的配置安装与项目创建
    log4j:WARN No appenders could be found for logger
    终于在博客园扎根了
    简单工厂模式
    详解apache防盗链网站图片防盗链方法
    怎样能写好文章标题
    生活需要阿Q精神
    2013个人博客全新起航
    华中师范大学新生网上怎么选宿舍
    华中师范大学2012级新生QQ交流群欢迎加入!
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3206230.html
Copyright © 2020-2023  润新知