uva10564

来源:互联网 发布:大数据安全管理 编辑:程序博客网 时间:2024/05/21 21:51

题目大意:
给一个如题目上给的图。要求从第一层走到最下面一层,只能往左下或右下走,经过的数字之和为sum。
问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径。

思路:
dp[i][j][k]表示从坐标(i,j)走到最后一层的和要为k的方案数。
由于它只能往左下或者右下走,所以dp[i][j][k] = dp[i + 1][j][k - val] + dp[i + 1][j + 1][k - val] 其中val分别表示坐标(i + 1,j),(i + 1,j + 1)的值。
我觉得输出对我来说又是一个难题。。

代码:

#include <stdio.h>#include <cstring>#include <iostream>using namespace std;const int INF =0x3f3f3f3f;int n,s;int num[50][22];long long dp[50][22][510];void init() {    for(int i = 1;i <= n; i++)        for(int j = 1; j <=n - i + 1; j++)            scanf("%d",&num[i][j]);    for(int i = n + 1; i <= 2 * n -1; i++)        for(int j = 1; j <= i + 1 - n; j++)            scanf("%d",&num[i][j]);}void print(int i,int j,int sum) {    if(i >= 2 * n - 1)        return;    int val = num[i][j];    if(i < n) {        if(j > 1 && dp[i + 1][j - 1][sum - val]) {            printf("L");            print(i + 1, j -1,sum - val);            return;        }        printf("R");        print(i + 1, j, sum - val);    }    else {        if(dp[i + 1][j][sum - val]) {            printf("L");            print(i + 1, j, sum - val);            return;        }        printf("R");        print(i + 1, j + 1,sum - val);    }}int main() {    while(scanf("%d %d",&n,&s) && n + s) {        init();        memset(dp,0,sizeof(dp));        for(int i = 1; i <= n; i++)            dp[2 * n - 1][i][num[2 * n -1][i]] = 1;        for(int i = 2 * n -2; i >= n; i--) {            for(int j = 1; j <= i + 1 - n; j++)                for(int v = num[i][j];v <= s; v++) {                    int w = num[i][j];                    dp[i][j][v] = dp[i + 1][j][v - w] + dp[i + 1][j + 1][v - w];                }        }        long long ans = 0;        for(int i = n - 1; i >= 1; i--) {            for(int j  =1; j <= n - i + 1; j++) {                for(int v = num[i][j]; v <= s; v++) {                    int w = num[i][j];                    if(j > 1) dp[i][j][v] += dp[i + 1][j - 1][v - w];                    if(j < n - i + 1) dp[i][j][v] += dp[i + 1][j][v - w];                }            if(i == 1)                ans += dp[1][j][s];            }        }        printf("%lld\n",ans);        for(int i = 1; i <= n; i++) {            if(dp[1][i][s]) {                printf("%d ", i -1);                print(1,i,s);                break;            }        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击