最大子段和与最大子矩阵和

  最大子段和。

  求一段连续的子段里面最大的值。

  

 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 }

 

posted @ 2018-05-15 19:22  flyer_duck  阅读(266)  评论(0编辑  收藏  举报