UVA 10564 - Paths through the Hourglass

来源:互联网 发布:网络歌手紫菱老公 编辑:程序博客网 时间:2024/05/18 00:51
import java.io.*;import java.math.BigInteger;import java.util.*;public class Main {    static int table[][] = new int[40][22];    static int s,n;    public static void main (String [] args) throws Exception {        Scanner scan = new Scanner(System.in);        while(true){            for(int i=0;i<40;i++){                Arrays.fill(table[i], 0);            }            s = scan.nextInt();            n = scan.nextInt();            if(s==0&&n==0) break;            int l = 2*s-1;            for(int i=1;i<=l;i++){                if(i<=s){                    table[i][0] = s+1-i;                }else{                    table[i][0] = i+1-s;                }                for(int j=1;j<=table[i][0];j++){                    table[i][j] = scan.nextInt();                }            }            long dp[][][] = new long[l+1][s+1][500];            for(int j=1;j<=s;j++){                dp[l][j][table[l][j]] = 1;            }            for(int i=l-1;i>=1;i--){                for(int j=1;j<=table[i][0];j++){                    for(int k=table[i][j];k<=n;k++){                        int offset = (i>=s)?1:-1;                        dp[i][j][k] = dp[i+1][j][k-table[i][j]];                        if(j+offset>=0){                            dp[i][j][k]+=dp[i+1][j+offset][k-table[i][j]];                        }                    }                }            }            long ans = 0; int start = -1;            for(int j=1;j<=s;j++){                ans+=dp[1][j][n];                if(dp[1][j][n]!=0&&start==-1){                    start = j;                }            }            System.out.println(ans);            String result = "";            if(ans!=0){                result+=start-1+" ";                int target = n-table[1][start];                for(int i=2;i<=l;i++){                    if(i<=s){                        if(start-1>=0&&dp[i][start-1][target]!=0){                            result+='L';                            target-=table[i][start-1];                            start-=1;                            continue;                        }                        if(dp[i][start][target]!=0){                            result+='R';                            target-=table[i][start];                        }                    }else{                        if(dp[i][start][target]!=0){                            result+='L';                            target-=table[i][start];                            continue;                        }                        if(start+1<=table[i][0]&&dp[i][start+1][target]!=0){                            result+='R';                            target-=table[i][start+1];                            start+=1;                        }                    }                }            }            System.out.println(result);        }    }}

哎呀,这个题目还是有点难啊。思路不算很简单, 然后整个代码对编程能力有一点要求。

dp[i][j][k]代表了在i,j这个点能组成K值的方法之和, K的范围是500

中间由于数组开小了,RE了N次,艹

dp[i][j][k]的值就取决于他下一层左右两个数

沙漏的上半部分和下半部分取左右值的方法是不一样的,也是这个题比较烦的地方。

还算是一个好题吧。集中暴露了代码和思维能力都不够。。。

尼玛后面这几个DP题都比较难搞啊。。。