hihocoder 1580 dp最大子矩阵和

Posted LuZhiyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder 1580 dp最大子矩阵和相关的知识,希望对你有一定的参考价值。

题意:

给出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最大子矩阵和的主要内容,如果未能解决你的问题,请参考以下文章

HihoCoder 1634 Puzzle Game(最大子矩阵和)题解

HihoCoder 1502 : 最大子矩阵 (双指针)

HihoCoder 1634 Puzzle Game

最大子段和||最大子矩阵和||最大全0子矩阵||最大全0子正方形

hdu 1081 dp问题:最大子矩阵和

hihoCoder #1664 : 01间隔方阵(DP)