傳送門: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