uva 1366(dp)

来源:互联网 发布:淘宝商品条形码 编辑:程序博客网 时间:2024/05/22 09:40

题意:有一个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;}
0 0
原创粉丝点击