题目描述
设有 N imes NN×N 的方格图 (N le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 。如下图所示(见样例):
A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
B
某人从图的左上角的 AA 点出发,可以向下行走,也可以向右走,直到到达右下角的 BB 点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字 00 )。
此人从 AA 点到 BB 点共走两次,试找出 22 条这样的路径,使得取得的数之和为最大。
输入输出格式
输入格式:
输入的第一行为一个整数 NN (表示 N imes NN×N 的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的 00 表示输入结束。
输出格式:
只需输出一个整数,表示 22 条路径上取得的最大的和。
输入输出样例
说明
NOIP 2000 提高组第四题
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <math.h> 5 #include <iostream> 6 7 using namespace std; 8 9 int dp[10][10][10][10]; 10 int map[10][10]; 11 12 int main() 13 { 14 int n; 15 scanf("%d", &n); 16 int x, y, val; 17 while (cin >> x >> y >> val&&x!=0) 18 map[x][y] = val; 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=n;j++) 21 for(int k=1;k<=n;k++) 22 for (int l = 1; l <= n; l++) { 23 dp[i][j][k][l] = max( max(dp[i - 1][j][k - 1][l],dp[i][j - 1][k][l - 1]),max(dp[i - 1][j][k][l - 1],dp[i][j - 1][k - 1][l]) )+map[i][j]+map[k][l]; 24 if (i == k && j == l) 25 dp[i][j][k][l] -= map[i][j]; 26 } 27 printf("%d ", dp[n][n][n][n]); 28 return 0; 29 }
思路:
多线程dp,将两次先后不同的路径看成是两个人同时出发
dp[a][b][c][d] 代表一个人走到 (a,b) ,另一个人走到 (c,d) 时,他们取到的最大和
我一开始没想通,觉得在式子
dp[a][b][c][d]=max(dp[a-1][b][c-1][d],dp[a][b-1][c][d-1],dp[a-1][b][c][d-1],dp[a][b-1][c-1][d])+map[a][b]+map[c][d]
中,如果 a=c+1&&b==d 时得到的结果很可能错误,后来发现,这个中间值根本没有意义,就算错了也无所谓