您的位置:首页 > 其它

POJ 2948 Martian Mining

2013-11-22 13:52 295 查看
题意:如下图,有一种n*m的网格,每个格子里可能分别有两种矿物a[i][j]和b[i][j],在网格的上边和左边分别有这两种矿物的收集站。对每个网格,可以建立向上或者向左的传送带,将该格所有矿物传送。但是,传送带不能变方向,否则变方向之前的矿物会从传送带上掉落下来。比如,矿物如果从(i,j)传送到(i,j-1),再传送到(i-1,j-1),就会掉落。问最终能收集到的矿物最多为多少(两种矿物数量之和)。

/*
* Author:  Plumrain
* Created Time:  2013-11-18 17:03
* File Name: DP-POJ-2948.cpp
*/
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define CLR(x) memset(x, 0, sizeof(x))

int n, m;
int d[505][505][2];
int x[505][505][2];
int nor[505][505], wes[505][505];

void init()
{
for (int t = 0; t < 2; ++ t)
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j)
scanf ("%d", &x[i][j][t]);

CLR (nor); CLR (wes);
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j){
wes[i][j] = (j ? x[i][j][0]+wes[i][j-1] : x[i][j][0]);
nor[i][j] = (i ? x[i][j][1]+nor[i-1][j] : x[i][j][1]);
}
}

int DP()
{
CLR (d);
d[0][0][0] = x[0][0][0]; d[0][0][1] = x[0][0][1];
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j){
if (!i && !j) continue;
d[i][j][0] = wes[i][j];
if (i)
d[i][j][0] += max(d[i-1][j][0], d[i-1][j][1]);
d[i][j][1] = nor[i][j];
if (j)
d[i][j][1] += max(d[i][j-1][0], d[i][j-1][1]);
}
return max(d[n-1][m-1][0], d[n-1][m-1][1]);
}

int main()
{
while (scanf ("%d%d", &n, &m) != EOF && n){
init();
printf ("%d\n", DP());
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: