传送门:https://hihocoder.com/problemset/problem/1634c++
题意:给你一个n*m(n,m<=150)的数字矩阵,每一个元素val(-1000<=val<=1000),以及一个数字p(-1000<=p<=1000)。你如今最多能够修改矩阵中的一个数字,改为p,求最大子矩阵的最小值git
思路:其实关键仍是想到,对于某个点(i,j),要么最大子矩阵(设值为ma)通过了这个点,要么没有通过这个点。若是没有通过这个点,咱们只须要统计其上下左右四个部分包含的最大子矩阵,记为tmp1,若是通过这个点,就将这个点替换为p,取tmp=max(tmp1,ma-a[i][j]+p)。spa
最后发现每一个点咱们均可以同时当作通过和没被通过这样取,由于不会影响最后的答案。最后取ans=min(ans,tmp)。.net
四个部分的求最大子矩阵时必定要想清楚每一重for的含义。。。code
代码:get
#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define mst(head,x,n) memset(head+1,x,n*sizeof(head[0])) #define rep(i,a,b) for(register int i=(a);i<=(b);i++) #define dep(i,a,b) for(register int i=(a);i>=(b);i--) using namespace std; const int maxn=150+5; const int MAXN=1e7+5; //const double pi=acos(-1.0); //const double eps=1e-9; //const ll mo=1e9+7; int n,m,k; int L[maxn],R[maxn],U[maxn],D[maxn]; int a[maxn][maxn],sum[maxn],c[maxn]; int ans,tmp,cnt; int flag; template <typename T> inline void read(T &X){ X=0;int w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); if(w) X=-X; } int main(){ int T,cas=1; //read(T); //while(T--) while(scanf("%d%d%d",&n,&m,&k)!=EOF) { //read(n);read(m);read(k); rep(i,1,n){ rep(j,1,m) scanf("%d",&a[i][j]); //read(a[i][j]); } rep(i,0,max(n,m)+1) L[i]=R[i]=U[i]=D[i]=-inf; rep(i,1,n){ rep(j,1,m) sum[j]=0; rep(j,i,n){ int tmp=0; rep(k,1,m){ sum[k]+=a[j][k]; tmp+=sum[k]; U[j]=max(U[j],tmp); if(tmp<0) tmp=0; } } U[i]=max(U[i],U[i-1]); } dep(i,n,1){ rep(j,1,m) sum[j]=0; dep(j,i,1){ int tmp=0; rep(k,1,m){ sum[k]+=a[j][k]; tmp+=sum[k]; D[j]=max(D[j],tmp); if(tmp<0) tmp=0; } } D[i]=max(D[i],D[i+1]); } rep(i,1,m){ rep(j,1,n) sum[j]=0; rep(j,i,m){ int tmp=0; rep(k,1,n){ sum[k]+=a[k][j]; tmp+=sum[k]; L[j]=max(L[j],tmp); if(tmp<0) tmp=0; } } L[i]=max(L[i],L[i-1]); } dep(i,m,1){ rep(j,1,n) sum[j]=0; dep(j,i,1){ int tmp=0; rep(k,1,n){ sum[k]+=a[k][j]; tmp+=sum[k]; R[j]=max(R[j],tmp); if(tmp<0) tmp=0; } } R[i]=max(R[i],R[i+1]); } int ans=U[n]; rep(i,1,n){ rep(j,1,m) { int tmp=-inf; tmp=max(U[i-1],D[i+1]); tmp=max(tmp,max(L[j-1],R[j+1])); tmp=max(tmp,U[n]-a[i][j]+k); ans=min(ans,tmp); } } printf("%d\n",ans); } return 0; }
本文分享 CSDN - LSD20164388。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。it