最大子段(阵)和

P1115 最大子段和

  这是一道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 }

HDU To The Max

  学完了最大子段和后,该学最大子阵和了(欸嘿嘿)。对于求二维的这玩意儿,咱们压成一位就能够了。确定会有人问,怎么压成一维?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 }
相关文章
相关标签/搜索