POJ 2948 Martian Mining [DP]

题意:不想复述了。。好累。。

思路:yey矿只能由东向西运送,用数组yey[i][j]表示地图中从(i, 1), (i, 2), ... 到 (i, j)的yey矿总量。blog矿只能由南向北运送,用数组blog[i][j]表示地图中从(1, j), (2, j), ... 到 (i, j)的blog矿总量。

而dp[i][j]表示左上顶点为(1, 1),右下顶点为(i, j)的矩形内按照题意可运送的矿产总量的最大值。则关键点就是位于(i, j)处的矿产。可以有两种选择,一种是从该点建一条向北的blog矿的传送带,另一种是从该点建一条向西的yey矿的传送带。由此可得dp的递推公式:

dp[i][j] = max(dp[i][j-1] + blog[i][j], dp[i-1][j] + yey[i][j]).

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #define maxn 505
 5 using namespace std;
 6 int yey[maxn][maxn], blog[maxn][maxn];
 7 int dp[maxn][maxn];
 8 int main()
 9 {
10     int n, m;
11     //freopen("data.in", "r", stdin);
12     while (~scanf("%d%d",&n,&m) && n && m)
13     {
14         memset(yey, 0, sizeof(yey));
15         memset(blog, 0, sizeof(blog));
16         memset(dp, 0, sizeof(dp));
17         for (int i = 1; i <= n; i++)
18             for (int j = 1; j <= m; j++)
19             {
20                 int a;
21                 scanf("%d",&a);
22                 yey[i][j] = yey[i][j-1] + a;
23             }
24         for (int i = 1; i <= n; i++)
25             for (int j = 1; j <= m; j++)
26             {
27                 int a;
28                 scanf("%d",&a);
29                 blog[i][j] = blog[i-1][j] + a;
30             }
31         for (int i = 1; i <= n; i++)
32             for (int j = 1; j <= m; j++)
33                 dp[i][j] = max(dp[i][j-1] + blog[i][j], dp[i-1][j] + yey[i][j]);
34         printf("%d\n",dp[n][m]);
35     }
36     return 0;
37 }

 

posted @ 2013-08-17 20:41  fenshen371  阅读(219)  评论(0编辑  收藏  举报