POJ 2948 Martian Mining(DP)这是POJ第200道,居然没发现

题目链接

两种矿石,Y和B,Y只能从从右到左,B是从下到上,每个空格只能是上下或者左右,具体看图。求左端+上端最大值。

很容易发现如果想最优,分界线一定是不下降的,分界线上面全是往上,分界线下面都是往左,然后就发现每一行,只和上一行有关系,DP可搞。

应该可以单调队列优化,我直接暴力水过了。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 int dp[501][501];
 8 int sum1[501][501];
 9 int sum2[501][501];
10 int p1[501][501];
11 int p2[501][501];
12 int main()
13 {
14     int n,m,i,j,k,ans;
15     while(scanf("%d%d",&n,&m)!=EOF)
16     {
17         if(n == 0&&m == 0) break;
18         memset(dp,0,sizeof(dp));
19         for(i = 1;i <= n;i ++)
20         {
21             for(j = 1;j <= m;j ++)
22             scanf("%d",&p1[i][j]);
23         }
24         for(i = 1;i <= n;i ++)
25         {
26             for(j = 1;j <= m;j ++)
27             scanf("%d",&p2[i][j]);
28         }
29         for(i = 1;i <= n;i ++)
30         {
31             for(j = 1;j <= m;j ++)
32             {
33                 sum1[i][j] = sum1[i][j-1] + p1[i][j];
34                 sum2[i][j] = sum2[i][j-1] + p2[i][j];
35             }
36         }
37         for(i = 1;i <= n;i ++)
38         {
39             for(j = 0;j <= m;j ++)
40             {
41                 for(k = 0;k <= j;k ++)
42                 {
43                     dp[i][j] = max(dp[i][j],dp[i-1][k]+sum1[i][j]+sum2[i][m]-sum2[i][j]);
44                 }
45             }
46         }
47         ans = 0;
48         for(i = 0;i <= m;i ++)
49         ans = max(ans,dp[n][i]);
50         printf("%d\n",ans);
51     }
52     return 0;
53 }

 

posted @ 2013-07-11 21:34  Naix_x  阅读(202)  评论(0编辑  收藏  举报