题意:有一个n*m的格子,每个格子里有A矿和B矿,A矿必须由右向左运输,B矿必须由下向上运输,给出两种矿在格子内的数量,挖矿人在每个格子里只能选一种矿挖,而且在格子内建运输管道不能拐弯或间断且都能通到格子外面。问最后能收集到的矿的总数最多多少。
题解:f[i][j][k]表示在前i行前j列第i行第j列挖k矿的最大数量,那么分两种情况
(1)第i行第j列挖A矿,那么(i,j)一定左边全是A矿,(i,j)上面可以是A也可以是B
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1]) + sumA[i][j]
(2)第i行第j列挖B矿,那么(i,j)一定上边全是B矿,(i,j)上面可以是A也可以是B
f[i][j][1] = max(f[i][j - 1][0], f[i][j - 1][1]) + sumB[i][j]
结果是max(f[n][m][0], f[n][m][1])
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 505;
int n, m, A[N][N], B[N][N], sumA[N][N], sumB[N][N];
int f[N][N][2];
int main() {
while (scanf("%d%d", &n, &m) == 2 && n + m) {
memset(f, 0, sizeof(f));
memset(sumA, 0, sizeof(sumA));
memset(sumB, 0, sizeof(sumB));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &A[i][j]);
sumA[i][j] = sumA[i][j - 1] + A[i][j];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &B[i][j]);
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
sumB[j][i] = sumB[j - 1][i] + B[j][i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1]) + sumA[i][j];
f[i][j][1] = max(f[i][j - 1][0], f[i][j - 1][1]) + sumB[i][j];
}
printf("%d\n", max(f[n][m][0], f[n][m][1]));
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 17:05:06