UVA 10564 Paths through the Hourglass(背包)

为了方便打印路径,考虑从下往上转移。dp[i][j][S]表示在i行j列总和为S的方案,

dp[i][j][S] = dp[i+1][left][S-x]+dp[i+1][right][S-x]

方案O(2^2*n-1),结果要用long long保存。

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 22,maxs = 501;
int hg[maxn<<1][maxn];
ll dp[maxn<<1][maxn][maxs];

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int n, S;
    while(scanf("%d%d", &n, &S) ,n){
        int rc = 0;
        for(int i = n; i > 1; i--){
            int *h = hg[rc++];
            for(int j = 1; j <= i; j++){
                scanf("%d",h+j);
            }
        }
        for(int i = 1; i <= n; i++){
            int *h = hg[rc++];
            for(int j = 1; j <= i; j++){
                scanf("%d",h+j);
            }
        }
        rc--;
        memset(dp,0,sizeof(dp));
        for(int j = 1; j <= n; j++){
            dp[rc][j][hg[rc][j]] = 1;
        }
        while(rc>=n){
            for(int j = 1, mj = (rc-- + 1) - n; j <= mj; j++){
                int x = hg[rc][j];
                ll *f = dp[rc][j];
                for(int s = S-x; s >= 0; s--){
                    f[s+x] = dp[rc+1][j][s]+dp[rc+1][j+1][s];
                }
            }
        }
        for(int i = 2; rc--,i <= n; i++){
            for(int j = 1; j <= i; j++){
                int x = hg[rc][j];
                ll *f = dp[rc][j];
                for(int s = S-x; s >= 0; s--){
                    f[s+x] = dp[rc+1][j-1][s]+dp[rc+1][j][s];
                }
            }
        }
        ll ans = 0;
        int index = 0;
        for(int j = 1; j <= n; j++){
            if(dp[0][j][S]){
                ans += dp[0][j][S];
                if(!index) index = j;
            }
        }
        printf("%lld\n",ans);
        if(ans){
            int j = index, s = S ;
            printf("%d ",j-1);
            rc = n;
            for(int i = 1; i < rc; i++){
                s -= hg[i-1][j];
                if(dp[i][j-1][s]){
                    putchar('L');
                    j--;
                }else {
                    putchar('R');
                }

            }
            rc = 2*n-1;
            for(int i = n; i < rc; i++){
                s -= hg[i-1][j];
                if(dp[i][j][s]){
                    putchar('L');
                }else {
                    j++;
                    putchar('R');
                }
            }
        }
        puts("");
    }
    return 0;
}

 

posted @ 2015-10-04 18:32  陈瑞宇  阅读(226)  评论(0编辑  收藏  举报