码迷,mamicode.com
首页 > 其他好文 > 详细

UVALive 3530 Martian Mining

时间:2015-10-03 23:09:03      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

分析:

对于网格grid[i][j]如果放向上的管道,那么grid[i][k], k>j 贪心地放向上的管道。

那么定义dp[i][j]表示第i行,最后一个放向左的管道是j的最大总矿量。

j = 0表示全放向上,j = m表示全放向左。

如果grid[i][j]要往放向上的管道的话,前提是grid[i-1][j]也要是向上的管道。

因此转移为dp[i][j] = max(dp[i-1][k]+sumA(1,j)+sumB(j+1,n) ), k >= j

对于N= 500这样的规模,转移有点慢。

对于sumA,sumB可以处理前缀和,

对于max(dp[i-1][k]),同样可以递推出来 max(dp[i-1][k]) = max(max(dp[i-1][k-1]),dp[i-1][k])

复杂度O(n*m)

窝觉得如果不是在做动态规划的专题窝可能不会往这方面去想。

#include<bits/stdc++.h>
using namespace std;

const int N = 501;
int A[N][N], B[N][N];
int dp[N][N];

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int n,m;
    while(scanf("%d%d",&n,&m),n){
        for(int i = 1; i <= n ;i++){
            for(int j = 1; j <= m; j++){
                scanf("%d",A[i]+j);
                A[i][j] += A[i][j-1];
            }
        }
        for(int i = 1; i <= n ;i++){
            for(int j = 1; j <= m; j++){
                scanf("%d",B[i]+j);
                B[i][j] += B[i][j-1];
            }
        }
        for(int j = 0; j <= m; j++){
            dp[1][j] = A[1][j] + B[1][m] - B[1][j];
        }
        for(int i = 2; i <= n; i++){
            dp[i][0] = dp[i-1][0];
            for(int j = 1; j <= m; j++){
                dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
            }
            for(int j = 0; j <= n; j++){
                dp[i][j] += A[i][j] + B[i][m] - B[i][j];
            }
        }
        int ans = 0;
        for(int j = 0; j <= m; j++){
            ans = max(ans,dp[n][j]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

UVALive 3530 Martian Mining

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4853940.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!