码迷,mamicode.com
首页 > 其他好文 > 详细

uva 1366(dp)

时间:2015-07-15 21:03:09      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:

题意:有一个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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

uva 1366(dp)

标签:

原文地址:http://blog.csdn.net/hyczms/article/details/46898395

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!