uva10564(DP+路径打印)
来源:互联网 发布:mix软件怎么拼图 编辑:程序博客网 时间:2024/06/07 22:22
这题的意思就是给出一个沙漏,第一行的两个数字n , s ;n就是沙漏的大小,最上面一行元素的个数,s就是目标权值.
要求问从第一行到最后一行所有路径中权值为s的路劲有几条.
然后输出字典序最小那条路是从第一行哪一个位置开始的(第一个是位置0),并输出这条路.
如果没有路径,输出一个空行.
首先,我们记(i,j)这个点权值为num[i][j] ,比如我们要知道从(i,j)这个位置到最后的权值为s的路径有多少条
那么我们要知道从(i + 1 , j) 这个位置到最后权值为s - num[i][j]的路径条数.
再加上从(i+ 1 , j - 1)这个位置到最后权值为s - num[i][j]的路径条数.
那么我们设f[i][j][s] 代表 从位置(i , j)到达最后,权值为s的路径有几条.
而且容易得到状态转移方程
f[i][j][s] = dp(i + 1 , j , s - num[i][j]) + dp(i + 1 , j - 1 , s -num[i][j]);但是有一点需要特别注意,在沙漏上半部,j 往下是 j - 1 和 j
但是在沙漏下半部,j往下 是 j 和 j +1; 所以需要判断 i < n,来决定用哪一个.
然后是要打印路径,因为要字典序最小,从左往右找到第一个可行的路径递归打印出来.
打印时只要判断往左走是否可达,可达就往左,否则往右.(保证最小)
打印时也要注意是在上半边,还是下半边:
AC代码:
#include<stdio.h>#include<string.h>#define ll long longconst int N = 50;int num[N][N];int l[N][N];int r[N][N];ll f[N][N][N * 10];int n,s,high;ll res;ll dp(int i , int j ,int s) {if(f[i][j][s] != -1)return f[i][j][s];if(num[i][j] == -1 || s < 0 )return 0;if(i == 2 * n - 1) {if(s == num[i][j])f[i][j][s] = 1;elsef[i][j][s] = 0;}else {if(i < n)f[i][j][s] = dp(i + 1 , j , s - num[i][j]) + dp(i + 1 , j - 1 , s -num[i][j]);elsef[i][j][s] = dp(i + 1 , j , s - num[i][j]) + dp(i + 1 , j + 1 , s -num[i][j]);}return f[i][j][s];}void print(int i , int j ,int s) {if(i == 2 * n -1) {printf("\n");return ;}if(i < n) {if(dp(i + 1 , j - 1, s - num[i][j]) > 0) {printf("L");print(i + 1 , j - 1 ,s - num[i][j]);}else {printf("R");print(i + 1 , j ,s - num[i][j]);}}else {if(dp(i + 1 , j, s - num[i][j]) > 0) {printf("L");print(i + 1 , j ,s - num[i][j]);}else {printf("R");print(i + 1 , j + 1 ,s - num[i][j]);}}}int main () {while(scanf("%d%d",&n,&s) && n + s) {memset(num, -1, sizeof(num));memset(f, -1 , sizeof(f));for(int i = 1; i < n; i++) { for(int j = 1; j <= (n-i+1); j++) { scanf("%d", &num[i][j]); } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= i; j++) { scanf("%d", &num[i+n-1][j]); } } res = 0 ;for (int i = 1 ; i <= n ; i++) {res += dp(1 , i , s);}printf("%lld\n",res);if(res == 0)printf("\n");else {for (int i = 1 ; ; i++) {if(f[1][i][s] != 0) {printf("%d ",i - 1);print(1 , i , s);break;}}}}}
0 0
- uva10564(DP+路径打印)
- uva10564
- uva10564
- uva10564
- UVa10564
- dp(UVa10564 - Paths through the Hourglass)
- zoj1463(区间dp+路径打印)
- uva 10564 DP+打印路径
- UVA10564-----Paths through the Hourglass-----简单的计数DP
- UVA 531 - Compromise(dp + LCS打印路径)
- UVA 531 DP LCS 打印路径
- hdu5092 Seam Carving(dp 打印路径)
- poj 1505 Copying Books (dp+路径打印)
- uva 116 Unidirectional TSP dp + 打印路径
- AC自动机+dp打印路径 hdu2296 Ring
- hash+dp打印路径 Codeforces615C Running Track
- poj 1141(区间dp+打印路径)
- POJ 1141 / UVa 1626 Brackets Sequence (区间DP&打印路径)
- 第一个APP:IOS做简单运算的计算器
- 12.22数据库判断数据库、表、字段是否存在
- 最简单的侧滑效果DrawerLayout
- 将html版API文档转换成chm格式的API文档
- 仿照着写个bootloader(四) 中断向量
- uva10564(DP+路径打印)
- kd树
- tomcat启动报错: 严重: createMBeans: Throwable java.lang.NullPointerException
- eyetribe_相关链接及功能
- 何必纠结JQuery
- VB.Net内存管理与内存释放的方法
- 继承和多态的难点总结
- 推荐算法之用户推荐(UserCF)和物品推荐(ItemCF)对比
- 玩转centos7(2)--最小化你的VMware