这是一道DP经典题(感受什么都经典)也是很常见的一个题型,具体思路就是用sum记录一个前缀和,从a[1]遍历到a[n]每次,加上去,可是一旦sum成了负数,就不必前缀和了,从新赋值0(由于前面就是累赘了)而后,就作出来了........php
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,maxx,sum; 4 int main() 5 { 6 scanf("%d%d",&n,&sum); 7 maxx=sum; 8 //先记录第一个值,由于全部都是负数时,maxx就会是0,因此要不预先处理,要不赋值负无穷 9 while(--n) 10 { 11 scanf("%d",&x); 12 sum=max(sum,0);//看负数就不要了 13 sum+=x;//加上去 14 maxx=max(maxx,sum);//曲最大子段和 15 } 16 printf("%d",maxx); 17 }
学完了最大子段和后,该学最大子阵和了(欸嘿嘿)。对于求二维的这玩意儿,咱们压成一位就能够了。确定会有人问,怎么压成一维?c++
康康这个样例,咱们枚举要选取的矩阵的宽度spa
(不要问我为何是竖着的,由于方便一些)code
而后咱们就把这两竖行压成一竖行blog
我知道竖着难受,可是....我懒得改了ci
而后咱们用正规的最大子段和求就好了啦get
至于这个压行的操做,咱们记录一个前缀和,枚举区间左右边界便可it
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,ans; 4 int mp[105][105]; 5 int qzh[105][105]; 6 int main() 7 { 8 while(cin>>n) 9 { 10 ans=-1e9;//必定要负无穷,避免后边负数,ans为0 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=n;j++) 13 scanf("%d",&mp[i][j]);//输入 14 for(int i=1;i<=n;i++) 15 for(int j=1;j<=n;j++) 16 qzh[i][j]=qzh[i][j-1]+mp[i][j];//前缀和(变量名生动形象) 17 for(int i=1;i<=n;i++)//枚举区间右下标 18 { 19 for(int j=0;j<i;j++)//枚举区间 左下标 20 { 21 int sum,maxx;//剩下就是最大子段和啦 22 sum=maxx=qzh[1][i]-qzh[1][j]; 23 for(int l=2;l<=n;l++) 24 { 25 int x=qzh[l][i]-qzh[l][j]; 26 sum=max(sum,0); 27 sum+=x; 28 maxx=max(maxx,sum); 29 } 30 ans=max(ans,maxx); 31 } 32 } 33 cout<<ans<<endl; 34 } 35 }