luogu 1121 环状最大两段子段和

时间:2022-12-22 10:39:31

题目大意:

一个序列看做一个环

选两段数使它们和最大

思路:

定义一个dp数组i j 0/1 表示前i个取了连续的j段 0/1表示取不取第i个

但是因为看做一个环

首尾相接的情况可以看做是选三段,其中第一个和最后一个必须取

然后dp就好了

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 200100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,a[MAXN],f[MAXN][][],ans;
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
memset(f,,sizeof(f));
f[][][]=a[];
for(int i=;i<=n;i++)
{
f[i][][]=max(f[i-][][],f[i-][][]);
f[i][][]=max(f[i-][][],)+a[i];
f[i][][]=max(f[i-][][],f[i-][][]);
f[i][][]=max(f[i-][][],max(f[i-][][],f[i-][][]))+a[i];
}
ans=max(f[n][][],f[n][][]);
memset(f,,sizeof(f));
f[][][]=a[];
for(int i=;i<=n;i++)
{
f[i][][]=max(f[i-][][],f[i-][][]);
f[i][][]=f[i-][][]+a[i];
f[i][][]=max(f[i-][][],f[i-][][]);
f[i][][]=max(f[i-][][],max(f[i-][][],f[i-][][]))+a[i];
f[i][][]=max(f[i-][][],f[i-][][]);
f[i][][]=max(f[i-][][],max(f[i-][][],f[i-][][]))+a[i];
}
printf("%d",max(ans,f[n][][]));
}