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 }

 

你可能感兴趣的:(poj)