您的位置:首页 > 其它

poj 2948 简单dp

2014-08-04 19:46 274 查看
这道题的题意比英语阅读理解还蛋疼,真的是太没有节操了。

读题读了快一个小时了才明白要干嘛,其实就是:火星上有yeyenum bloggium两种矿石,yeyenum只能东西方向运送到最西端,bloggium只能南北方向运送到最北端。如果这个方格已经建立了东西方向的传送带,则不能再建立南北方向的传送带。已知yeyenum和bloggium的在棋盘上的分布,求运送到最北端和最西端的最大总运送量。。。

由题意知道,要么横着(由东到西)要么竖着(由南到北)。所以我们先预处理一下,然后再递推。

我们设dp[i][j]为map[1][1]到map[i][j] 区域的最大运送量。sumr[i][j]为yeyenum矿石的 第i行的前j个数的和,sumc[i][j] 为bloggium矿石的 第j列的前i行个数的和。

那么: dp[i][j]=max(dp[i-1][j]+sumr[i][j],dp[i][j-1]+sumc[i][j]);

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 555
using namespace std;
int mapr[MAX][MAX],mapc[MAX][MAX];
int sumr[MAX][MAX],sumc[MAX][MAX];
int dp[MAX][MAX];
int n,m;
void input()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&mapr[i][j]);
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&mapc[i][j]);
}
}
}
void deal()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
sumr[i][j]=sumr[i][j-1]+mapr[i][j];
}
}
for(j=1;j<=m;j++)
{
for(i=1;i<=n;i++)
{
sumc[i][j]=sumc[i-1][j]+mapc[i][j];
}
}
}
void work()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j]+sumr[i][j],dp[i][j-1]+sumc[i][j]);
}
}
printf("%d\n",dp
[m]);
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m),n)
{
input();
deal();
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: