题目传送门
1 /*
2 01背包(类):dp[i][j][k] 表示从(i, j)出发的和为k的方案数,那么cnt = sum (dp[1][i][s])
3 状态转移方程:dp[i][j][k] = dp[i+1][j][k-c] + dp[i+1][j+1][k-c];(下半部分) 上半部分类似
4 因为要输出字典序最小的,打印路径时先考虑L
5 */
6 /************************************************
7 * Author :Running_Time
8 * Created Time :2015-8-9 15:45:11
9 * File Name :UVA_10564.cpp
10 ************************************************/
11
12 #include <cstdio>
13 #include <algorithm>
14 #include <iostream>
15 #include <sstream>
16 #include <cstring>
17 #include <cmath>
18 #include <string>
19 #include <vector>
20 #include <queue>
21 #include <deque>
22 #include <stack>
23 #include <list>
24 #include <map>
25 #include <set>
26 #include <bitset>
27 #include <cstdlib>
28 #include <ctime>
29 using namespace std;
30
31 #define lson l, mid, rt << 1
32 #define rson mid + 1, r, rt << 1 | 1
33 typedef long long ll;
34 const int MAXN = 22;
35 const int MAXS = 5e2 + 10;
36 const int INF = 0x3f3f3f3f;
37 const int MOD = 1e9 + 7;
38 int a[MAXN*2][MAXN];
39 ll dp[MAXN*2][MAXN][MAXS];
40 int n, s;
41
42 void print(int x, int y, int sum) {
43 if (x >= 2 * n - 1) return ;
44 int v = a[x][y];
45 if (x < n) {
46 if (y > 1 && dp[x+1][y-1][sum-v]) {
47 printf ("L"); print (x+1, y-1, sum - v);
48 }
49 else {
50 printf ("R"); print (x+1, y, sum - v);
51 }
52 }
53 else {
54 if (dp[x+1][y][sum-v]) {
55 printf ("L"); print (x+1, y, sum - v);
56 }
57 else {
58 printf ("R"); print (x+1, y+1, sum - v);
59 }
60 }
61 }
62
63 int main(void) { //UVA 10564 Paths through the Hourglass
64 while (scanf ("%d%d", &n, &s) == 2) {
65 if (!n && !s) break;
66 for (int i=1; i<=n; ++i) {
67 for (int j=1; j<=n-i+1; ++j) scanf ("%d", &a[i][j]);
68 }
69 for (int i=n+1; i<=2*n-1; ++i) {
70 for (int j=1; j<=i-n+1; ++j) scanf ("%d", &a[i][j]);
71 }
72
73 memset (dp, 0, sizeof (dp));
74 for (int i=1; i<=n; ++i) {
75 int c = a[2*n-1][i];
76 dp[2*n-1][i][c] = 1;
77 }
78 for (int i=2*n-2; i>=n; --i) {
79 for (int j=1; j<=i-n+1; ++j) {
80 int c = a[i][j];
81 for (int k=c; k<=s; ++k) {
82 dp[i][j][k] = dp[i+1][j][k-c] + dp[i+1][j+1][k-c];
83 }
84 }
85 }
86 ll cnt = 0;
87 for (int i=n-1; i>=1; --i) {
88 for (int j=1; j<=n-i+1; ++j) {
89 int c = a[i][j];
90 for (int k=c; k<=s; ++k) {
91 if (j > 1) dp[i][j][k] += dp[i+1][j-1][k-c];
92 if (j < n - i + 1) dp[i][j][k] += dp[i+1][j][k-c];
93 }
94 if (i == 1) cnt += dp[i][j][s];
95 }
96 }
97 printf ("%lld
", cnt);
98 for (int i=1; i<=n; ++i) {
99 if (dp[1][i][s]) {
100 printf ("%d ", i-1);
101 print (1, i, s); break;
102 }
103 }
104 puts ("");
105 }
106
107 return 0;
108 }