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

    }

}


 


 

你可能感兴趣的:(递归)