UVA 10564 Paths through the Hourglass
2013-01-19 17:59
477 查看
大意:有一个沙漏,从第一行开始走,每次往下走一行,往左或者往右走一列,不能走出沙漏。你的目标是让沿途经过的所有整数之和恰好为一个给定的整数。求出符合条件的路径条数。
思路:求路径条数,这很常见,令d[i][j][s]表示以第i行,j列的元素为起点,累加的和为s的路径条数,从上往下走,只要走到终点,则令终点的值为1,这样在搜索时就可以很方便的求出结果。
这一题还有一个问题不好解决,如果只有上三角形的话,很好解决,那么多了一个下三角形,那么选择向左走还是向右走的时候,方向可能会紊乱,所以我我们可以另外开两个数组L,R来表示当前点的左边应该怎么操作,右边应该怎么操作。
然后记忆化搜索时,注意没有越界,而且走到最底层时,要判断累加和是否为初始时的s,是,路径为1,否,路径为0。
打印路径时,从第一行开始扫,遇到第一个非0数则退出,然后递归打印路径。
思路:求路径条数,这很常见,令d[i][j][s]表示以第i行,j列的元素为起点,累加的和为s的路径条数,从上往下走,只要走到终点,则令终点的值为1,这样在搜索时就可以很方便的求出结果。
这一题还有一个问题不好解决,如果只有上三角形的话,很好解决,那么多了一个下三角形,那么选择向左走还是向右走的时候,方向可能会紊乱,所以我我们可以另外开两个数组L,R来表示当前点的左边应该怎么操作,右边应该怎么操作。
然后记忆化搜索时,注意没有越界,而且走到最底层时,要判断累加和是否为初始时的s,是,路径为1,否,路径为0。
打印路径时,从第一行开始扫,遇到第一个非0数则退出,然后递归打印路径。
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <string> #include <algorithm> using namespace std; int n, s; typedef long long LL; LL d[50][50][510]; int vis[50][50][510]; int L[50][50], R[50][50]; int A[50][50]; void init() { memset(A, -1, sizeof(A)); memset(vis, 0, sizeof(vis)); memset(L, 0, sizeof(L)); memset(R, 0, sizeof(R)); } void read_case() { init(); for(int i = 1; i < n; i++) { for(int j = 1; j <= (n-i+1); j++) { scanf("%d", &A[i][j]); L[i][j] = j-1; R[i][j] = j; } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= i; j++) { scanf("%d", &A[i+n-1][j]); L[n+i-1][j] = j; R[n+i-1][j] = j+1; } } } LL dp(int i, int j, int s) { LL &ans = d[i][j][s]; if(vis[i][j][s]) return ans; vis[i][j][s] = 1; if(A[i][j] == -1 || s < 0) ans = 0; //边界条件 else if(i == 2*n-1) //边界条件 { if(s == A[i][j]) ans = 1; else ans = 0; } else { s -= A[i][j]; ans = dp(i+1, L[i][j], s) + dp(i+1, R[i][j], s); } return ans; } void print_ans(int i, int j, int s) { if(i == 2*n-1) { printf("\n"); return ; } else { s -= A[i][j]; if(dp(i+1, L[i][j], s) > 0) //如果存在路径 { printf("L"); print_ans(i+1, L[i][j], s); } else { printf("R"); print_ans(i+1, R[i][j], s); } } } void solve() { int i, j; read_case(); LL ans = 0; for(i = 1; i <= n; i++) ans += dp(1, i, s); printf("%lld\n", ans); if(ans == 0) { printf("\n"); return ;} for(j = 1; dp(1, j, s) == 0; j++) ; //从左往右第一个不为0的数 printf("%d ", j-1); print_ans(1, j, s); } int main() { while(scanf("%d%d", &n, &s) && (n || s)) { solve(); } return 0; } /*void print_ans() //非递归打印路径 { int i, j; for(j = 1; dp(1, j, s) == 0; j++) ; printf("%d ", j-1); for(int i = 1; i < 2*n-1; i++) { s -= A[i][j]; int c = dp(i+1, L[i][j], s); if(c > 0) { printf("L"); j = L[i][j]; } else { printf("R"); j = R[i][j]; } } printf("\n"); }*/
相关文章推荐
- UVA 10564 Paths through the Hourglass
- UVA 10564 Paths through the Hourglass
- uva 10564 - Paths through the Hourglass(dp)
- UVa 10564 - Paths through the Hourglass (简单DP)
- uva 10564 Paths through the Hourglass
- UVA 10564 - Paths through the Hourglass (dp)
- UVa10564 - Paths through the Hourglass(dp)
- UVA - 10564 Paths through the Hourglass
- uva 10564 - Paths through the Hourglass(dp)
- UVA 10564 Paths through the Hourglass(递推)
- UVA 10564 十 Paths through the Hourglass
- uva 10564 - Paths through the Hourglass 沙漏里的路径 最优解+路径输出
- UVa 10564 - Paths through the Hourglass(DP)
- UVA 10564_ Paths through the Hourglass
- UVA 10564 - Paths through the Hourglass
- uva 10564 Paths through the Hourglass(DP)
- uva 10564 Paths through the Hourglass
- UVA 10564_ Paths through the Hourglass
- 01背包(类) UVA 10564 Paths through the Hourglass
- UVA 10564 Paths through the Hourglass(dp)