最大子段和与最大子矩阵和
最大子段和。
求一段连续的子段里面最大的值。
1 #include<stdio.h> 2 const int maxn=10006; 3 int a[maxn]; 4 5 int main() 6 { 7 int n; 8 while( ~scanf("%d",&n)){ 9 10 int ans=0,mid=0; 11 for(int i=1;i<=n;i++){ 12 scanf("%d",&a[i]); 13 } 14 15 for(int i=1;i<=n;i++){ 16 if(mid<=0) mid=a[i]; ///小于0时要更新区间 17 else mid+=a[i]; 18 if(ans<mid) ans=mid; 19 } 20 printf("%d\n",ans); 21 } 22 return 0; 23 }
最大子矩阵和
求最大子矩阵的和,建立在最大子段和之上。
关键的思维转换:将子矩阵的上下行相加,加为一行,问题转化为求最大子段和。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=406; 6 int a[maxn][maxn],b[maxn]; 7 int X,Y; 8 9 int maxline(int en) 10 { 11 int mid=0,res=0; 12 for(int i=1;i<=en;i++){ 13 if(mid<=0) mid=b[i]; 14 else mid+=b[i]; 15 res=max(mid,res); 16 } 17 return res; 18 } 19 20 int Maxsum(int m,int n) 21 { 22 int ans=0; 23 for(int i=1;i<=m;i++){ ///枚举每一行 24 memset( b, 0, sizeof b); 25 for(int j=i;j<=m;j++){ ///以第i行,为起点,向下求和 26 for(int k=1;k<=n;k++) 27 b[k]+=a[j][k]; ///每行相加的数段 28 int sum=maxline(n); ///maxline为最大字段和的求解 29 ans=max(ans,sum); 30 } 31 } 32 return ans; 33 } 34 35 int main() 36 { 37 ios::sync_with_stdio(0); std::cin.tie(0); 38 int m,n,T; 39 while( cin >> m >> n){ 40 41 for(int i=1;i<=m;i++) 42 for(int j=1;j<=n;j++) 43 cin >> a[i][j]; 44 45 cout << Maxsum( m, n) <<endl; ///Maxsum为solve 46 } 47 return 0; 48 }