UVA1366-----Martian Mining------DP

来源:互联网 发布:java解压缩rar文件 编辑:程序博客网 时间:2024/05/22 02:38

本文出自:http://blog.csdn.net/dr5459

题目地址:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4112

题目地址:

给你一个N*M的地图,每个点都有A矿和B矿

A矿只能从左边往右边运输,B矿只能从上往下运输,中间不能拐弯,也不能间断

问你最多能采集的A和B之和

解题思路:

从题目可以发现如果在节点(i,j)上运输A的话,那么第i行的第1~j列只能运输A

同理,如果运输B的话,那么第j列的第1~i行只能运输B

给出状态表达式

定义:dp[i][j][0]表示如果在(i,j)上运输A的话的总和

dp[i][j][1]表示B的

那么转移方程就为:

dp[i][j][0] = max(dp[i-1][j][0],dp[i-1][j][1])+第i行第1~j列的A之和

dp[i][j][1] = max(dp[i][j-1][0],dp[i][j-1][1])+第j列第1~i行的B之和

行的和或者列的和预处理一下

最后的最优值就是max(dp[n][m][0],dp[n][m][1])


代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn = 510;int dp[maxn][maxn][2];int sum1[maxn][maxn];int sum2[maxn][maxn];int main(){    int n,m;    while(~scanf("%d%d",&n,&m) && n+m)    {        memset(dp,0,sizeof(dp));        memset(sum1,0,sizeof(sum1));        memset(sum2,0,sizeof(sum2));        int tmp;        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                scanf("%d",&tmp);                sum1[i][j] = sum1[i][j-1]+tmp;            }        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                scanf("%d",&tmp);                sum2[i][j] = sum2[i-1][j]+tmp;            }        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                dp[i][j][0] = max(dp[i-1][j][0],dp[i-1][j][1])+sum1[i][j];                dp[i][j][1] = max(dp[i][j-1][0],dp[i][j-1][1])+sum2[i][j];            }        }        printf("%d\n",max(dp[n][m][0],dp[n][m][1]));    }    return 0;}


原创粉丝点击