开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
题目:给出一段长度为 n 的环状序列 a,即认为 a1 和 an 是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大。
思路:
两种情况
1.000----000---000
2.----0000---000---
0代表选了这个数,-代表没选;第二种情况可以由正着求一遍再反着求一遍最大子段和,然后枚举断点拼接;第一种可以换一个思路求出最小的两段然后用总和减去就可以了,为了方便可以直接让a[i]取负再跑一遍就行
这是子段和的方法
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<ctime>
#define ll long long
#define CHECK(x,y) (x>0&&x<=n&&y>0&&y<=m)
//#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int n,sum=0,a[200005],tot=0,f[200005],g[200005];
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
memset(f,-64,sizeof(f));
for(int i=1;i<=n;i++)f[i]=max(f[i-1],0)+a[i];
for(int i=1;i<=n;i++)f[i]=max(f[i],f[i-1]);
int maxx=-inf;
for(int i=1;i<=n;i++)
maxx=max(maxx,f[i]);
cout<<maxx<<endl;
return 0;
}
这是题解代码
#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e9;
const double pi=acos(-1);
const int N=1e6+100;
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int n,a[200005],f[200005],g[200005];
int ask(){
for(int i=1;i<=n;i++) f[i]=max(f[i-1],0LL)+a[i];
for(int i=1;i<=n;i++) f[i]=max(f[i-1],f[i]);
for(int i=n;i>=1;i--) g[i]=max(g[i+1],0LL)+a[i];
for(int i=n;i>=1;i--) g[i]=max(g[i+1],g[i]);
int res=-inf;
for(int i=1;i<=n;i++) res=max(res,f[i]+g[i+1]);
return res;
}
signed main()
{
//ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
int zn=0,sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
if(a[i]>0) zn++;
}
memset(f, ~0x7f, sizeof(f));
memset(g, ~0x7f, sizeof(g));
int ans=ask();
if(zn==1){cout<<ans<<endl;return 0;}
for(int i=1;i<=n;i++) a[i]*=-1;
ans=max(ans,(sum+ask())?(sum+ask()):-inf);
cout<<ans<<endl;
return 0;
}