网上的题解几乎都是一样的:
d(i, j, 0)表示前i行前j列,第(i, j)个格子向左运输能得到的最大值。
d(i, j, 1)是第(i, j)个格子向上运输能得到的最大值。
但是有一个很关键的问题没有解释:
某个格子中的A矿或者B矿一定有其中一种能够运出来吗?有没有可能这个格子没有修建管道,仅仅是为了给其他管道让路,使得总体取得最大值呢?
从题解的状态转移方程上来看,不会的。
自己YY了好久,也没有想到一个能严格证明的方法。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 500 + 10; 8 9 int A[maxn][maxn], B[maxn][maxn]; 10 int d[maxn][maxn][2]; 11 12 int main() 13 { 14 int n, m; 15 while(scanf("%d%d", &n, &m) && n) 16 { 17 for(int i = 1; i <= n; i++) 18 for(int j = 1; j <= m; j++) scanf("%d", &A[i][j]); 19 for(int i = 1; i <= n; i++) 20 for(int j = 1; j <= m; j++) scanf("%d", &B[i][j]); 21 22 for(int i = 1; i <= n; i++) 23 for(int j = 1; j <= m; j++) A[i][j] += A[i][j-1], B[i][j] += B[i-1][j]; 24 25 for(int i = 1; i <= n; i++) 26 for(int j = 1; j <= m; j++) 27 { 28 d[i][j][0] = max(d[i-1][j][0], d[i-1][j][1]) + A[i][j]; 29 d[i][j][1] = max(d[i][j-1][0], d[i][j-1][1]) + B[i][j]; 30 } 31 printf("%d\n", max(d[n][m][0], d[n][m][1])); 32 } 33 34 return 0; 35 }
代码君
时间: 2024-10-16 13:50:12