UVA 10564 Paths through the Hourglass

来源:互联网 发布:回家吃饭软件 编辑:程序博客网 时间:2024/06/16 03:30

题意: 给一个漏斗形状的矩阵,让你从最上面走到最下面,问有几种走法。并打印下标最小路径。

解法: 设dp[i][j]为走到第i行j列时有几种走法。简单DP一下就可以得到,对于要求的下标最小路径,我们可以在DP时从最下方递推上来,然后就可以很方便的从最上方一遍递推找出要求的路径了。

这道题本身不难,但是需要考虑每一个下标的细节,然后打印路径实在是恶心啊,瞬间身心俱疲。

/* **********************************************Author      : NeroCreated Time: 2013-8-26 2:12:08Problem id  : UVA 10564Problem Name: Paths through the Hourglass*********************************************** */#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define REP(i,a,b) for(int i=(a); i<(int)(b); i++)#define clr(a,b) memset(a,b,sizeof(a))typedef long long lld;int x[42][22];lld dp[42][22][400];int n,m;int main() {    while(~scanf("%d%d", &n, &m), n || m) {        clr(dp, 0);        for(int i = 1; i <= n; i ++) {            for(int j = 1; j <= n-i+1; j ++) scanf("%d", &x[i][j]);        }        for(int i = n+1; i <= 2*n-1; i ++) {            for(int j = 1; j <= i-n+1; j ++) scanf("%d", &x[i][j]);        }        if(m > 9 * (2*n-1)) {            printf("0\n\n");            continue;        }        for(int i = 1; i <= n; i ++) dp[2*n-1][i][x[2*n-1][i]] = 1;        for(int i = 2*n-2; i >= n; i --) {            for(int j = 1; j <= i-n+1; j ++) {                for(int k = x[i][j]; k <= m; k ++) {                    dp[i][j][k] += dp[i+1][j][k-x[i][j]] + dp[i+1][j+1][k-x[i][j]];                }            }        }        for(int i = n; i >= 2; i --) {            for(int j = 1; j <= n-i+1; j ++) {                for(int k = 0; k <= m; k ++) {                    if(k+x[i-1][j] <= m) dp[i-1][j][k+x[i-1][j]] += dp[i][j][k];                    if(k+x[i-1][j+1] <= m) dp[i-1][j+1][k+x[i-1][j+1]] += dp[i][j][k];                }            }        }        lld ans = 0;        for(int i = 1; i <= n; i ++) ans += dp[1][i][m];        printf("%lld\n", ans);        for(int j = 1; j <= n; j ++) if(dp[1][j][m]) {             printf("%d ", j-1);             for(int i = 1; i < n; i ++) {                if(dp[i+1][j-1][m-x[i][j]]) {                    printf("L");                    m -= x[i][j];                    j --;                }                else {                    printf("R");                    m -= x[i][j];                }             }             for(int i = n; i < 2*n-1; i ++) {                if(dp[i+1][j][m-x[i][j]]) {                    printf("L");                    m -= x[i][j];                }                else {                    printf("R");                    m -= x[i][j];                    j ++;                }             }             break;        }        printf("\n");    }    return 0;}


原创粉丝点击