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

hihocoder 1580 dp最大子矩阵和

时间:2017-09-25 22:55:39      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:ima   http   col   压缩   std   替换   print   元素   stdin   

技术分享

题意:

给出n*m的矩阵求最大子矩阵和,要求必须把矩阵中的某一个元素替换成p

代码:

//求最大子矩阵和,容易想到压缩之后dp但是这道题要求必须替换一次p,必然优先替换最小的。
//这样如果求得的结果恰好等于这个矩阵所有的元素的
//和但不是整个矩阵,并且没有替换元素结果就不对了,需要特判一下这种情况。比如以下两组数据:
//2 2 -4  2 2 -4
//1 -1    1  1
//1  1    1  1        dp求出来的结果分别是2和4并且没有替换p。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
int mp[309][309],b[309],c[309],f[309][2];
int n,m,p,ans;
void dp()
{
    memset(f,0,sizeof(f));
    for(int i=1;i<=m;i++){
        f[i][0]=max(f[i-1][0],0)+b[i];
        f[i][1]=max(f[i-1][1]+b[i],f[i][0]-c[i]+p);
        ans=max(ans,max(f[i][0],f[i][1]));
    }
}
void solve()
{
    for(int i=1;i<=m;i++){
        int sum=0,min_a=INF;
        for(int j=i;j<=m;j++){
            sum+=b[j];
            min_a=min(min_a,c[j]);
            if(i==1&&j==m) ans=max(ans,sum-min_a+p);
            else ans=max(ans,max(sum,sum-min_a+p));
        }
    }
}
int main()
{
    freopen("in.txt","r",stdin);
    while(scanf("%d%d%d",&n,&m,&p)==3){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
                scanf("%d",&mp[i][j]);
        }
        ans=-INF;
        for(int i=1;i<=n;i++){
            memset(b,0,sizeof(b));
            memset(c,INF,sizeof(c));
            for(int j=i;j<=n;j++){
                for(int k=1;k<=m;k++){
                    b[k]+=mp[j][k];
                    c[k]=min(c[k],mp[j][k]);
                }
                if(i==1&&j==n) solve();
                else dp();
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

hihocoder 1580 dp最大子矩阵和

标签:ima   http   col   压缩   std   替换   print   元素   stdin   

原文地址:http://www.cnblogs.com/--ZHIYUAN/p/7594256.html

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