51Nod 1051 - 最大子矩陣和(DP)
阿新 • • 發佈:2018-11-08
題目連結 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1051
【題目描述】
一個M*N的矩陣,找到此矩陣的一個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。
例如:3×3的矩陣:
-1 3 -1
2 -1 3
-3 1 2
和最大的子矩陣是:
3 -1
-1 3
1 2
Input
第1行:M和N,中間用空格隔開(2 <= M,N <= 500)。
第2 - N + 1行:矩陣中的元素,每行M個數,中間用空格隔開。(-10^9 <= M[i] <= 10^9)
Output
輸出和的最大值。如果所有數都是負數,就輸出0。
Input示例
3 3
-1 3 -1
2 -1 3
-3 1 2
Output示例
7
【思路】
這篇部落格講的很詳細 最大子矩陣,本質上就是字首和+最大子段和
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=505; int n,m; ll a[maxn]; ll g[maxn][maxn]; int main(){ scanf("%d%d",&m,&n); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ scanf("%lld",&g[i][j]); } } for(int i=2;i<=n;++i){ for(int j=1;j<=m;++j){ g[i][j]+=g[i-1][j]; } } ll ans=g[1][1]; for(int i=1;i<=n;++i){ for(int j=i;j<=n;++j){ for(int k=1;k<=m;++k) a[k]=g[j][k]-g[i-1][k]; ll tmp=a[1],res=a[1]; for(int k=2;k<=m;++k){ if(tmp>0) tmp+=a[k]; else tmp=a[k]; res=max(res,tmp); } ans=max(ans,res); } } printf("%lld\n",ans); return 0; }