[原创]hrbusr 1214&PID314 / [NOIP2000]方格取数 [多线程DP] [原创]hrbusr 1214&PID314 / [NOIP2000]方格取数 [多线程 DP]
2016-03-12 14:07:12 Tabris_ 阅读数:556
博客爬取于 2020-06-14 22:44:52 以下为正文
版权声明:本文为 Tabris 原创文章,未经博主允许不得私自转载。 https://blog.csdn.net/qq_33184171/article/details/50865290
题目描述 设有 NN 的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 0。如下图所示(见样例): 某人从图的左上角的 A 点出发,可以向下行走,也可以向右走,直到到达右下角的 B 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 0)。 此人从 A 点到 B 点共走两次,试找出 2 条这样的路径,使得取得的数之和为最大。 输入格式 输入的第一行为一个整数 N(表示 N N 的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的 0 表示输入结束。 输出格式 只需输出一个整数,表示 2 条路径上取得的最大的和。
Sample Input 8 2 3 13 2 6 6 3 5 7 4 4 14 5 2 21 5 6 4 6 3 15 7 2 14 0 0 0 Sample Output 67
本题是一个多线程 DP 总体思路就是一个 dp[x1][y1][x2][y2],来表示从 x1,y1 到 x2,y2 最多能够拿到的数值 在这里已经是两条路径所能的和最大值了 依次向下规划 就得到最终的结果
附本题代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include<iostream> # include <stdio.h> # include <string.h> # include<algorithm> using namespace std; const int MAXN=11; int g[MAXN][MAXN]; int sum[MAXN][MAXN][MAXN][MAXN]; int max(int a, int b) { if(a>b) return a; else return b; } int main() { int n; int x,y,z; while(scanf("%d",&n)!=EOF) { memset(sum, 0, sizeof(sum)); memset(g, 0,sizeof(g)); while(1) { scanf("%d %d %d", &x, &y, &z); if(x == 0 && y == 0 && z == 0) break; g[x][y] = z; } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { for(int k=1; k<=n; k++) { for(int e=1; e<=n; e++) { sum[i][j][k][e] = max(max(sum[i-1][j][k-1][e], sum[i][j-1][k][e-1]), max(sum[i-1][j][k][e-1], sum[i][j-1][k-1][e])); sum[i][j][k][e] += g[i][j]; if(i!=k || j!=e) sum[i][j][k][e] += g[k][e]; } } } } printf("%d\n",sum[n][n][n][n]); } return 0; }
以为题目规定了 只能向右向下走,所以 很多步是走不到的 完全可以在优化一维 用三维 dp 来解题 如果理解了题目 很容易就能写出 这里就不赘述了