算法笔记--最大子段和问题
Posted Wisdom+.+
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法笔记--最大子段和问题相关的知识,希望对你有一定的参考价值。
1.非连续最大子段和
如果不全为负数,最大子段和所有大于等于0的元素的和;如果全为负数,最大子段和为最大的负数。
2.连续最大子段和
①无长度限制:
例题:
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int N=2e5+5; int a[N]; int main() { int n; cin>>n; for(int i=0;i<n;i++)cin>>a[i]; int temp=0; int ans=0; int maxn=-INF; bool flag=true; for(int i=0;i<n;i++) { temp+=a[i]; maxn=max(maxn,a[i]); if(a[i]>=0)flag=false; if(temp<0) { temp=0; } ans=max(ans,temp); } if(flag)cout<<maxn<<endl; else cout<<ans<<endl; return 0; }
安利一下我们学校的oj
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; const int INF=0x3f3f3f3f; int sum[N]; int a,maxsum,minsum; int main() { ios::sync_with_stdio(false); cin.tie(0); int t; cin>>t; int l,r; int ansl,ansr,ans; for(int i=1;i<=t;i++) { memset(sum,0,sizeof(sum)); maxsum=-INF; minsum=0; ans=-INF; int ma=-INF; l=0; int ll=0; bool flag=false; int n; cin>>n; for(int i=1;i<=n;i++) { int a; cin>>a; if(a>ma) { ma=a; ll=i; } if(a>=0)flag=true; sum[i]=sum[i-1]+a; if(sum[i]>maxsum) { maxsum=sum[i]; r=i; } if(sum[i]<minsum) { minsum=sum[i]; l=i; } if(sum[r]-sum[l]>ans&&r>l) { ans=sum[r]-sum[l]; ansl=l+1; ansr=r; } } cout<<"Payoff "<<i<<":"<<endl; if(flag)cout<<ans<<‘ ‘<<ansl<<‘ ‘<<ansr<<endl; else cout<<ma<<‘ ‘<<ll<<‘ ‘<<ll<<endl; cout<<endl; } return 0; }
②有长度限制(如最大连续奇数字段和)
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int a[N]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++)cin>>a[i]; int sum=a[0],ans=a[0]; for(int i=1;i<n-1;i+=2) { sum+=a[i]+a[i+1]; if(sum<a[i+1])sum=a[i+1]; ans=max(ans,sum); } sum=a[1]; for(int i=2;i<n-1;i+=2) { sum+=a[i]+a[i+1]; if(sum<a[i+1])sum=a[i+1]; ans=max(ans,sum); } cout<<ans<<endl; } return 0; }
以上是关于算法笔记--最大子段和问题的主要内容,如果未能解决你的问题,请参考以下文章