题目大意:
一个序列看做一个环
选两段数使它们和最大
思路:
定义一个dp数组i j 0/1 表示前i个取了连续的j段 0/1表示取不取第i个
但是因为看做一个环
首尾相接的情况可以看做是选三段,其中第一个和最后一个必须取
然后dp就好了
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 200100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,a[MAXN],f[MAXN][4][2],ans; 21 int main() 22 { 23 n=read(); 24 for(int i=1;i<=n;i++) a[i]=read(); 25 memset(f,128,sizeof(f)); 26 f[1][1][1]=a[1]; 27 for(int i=2;i<=n;i++) 28 { 29 f[i][1][0]=max(f[i-1][1][0],f[i-1][1][1]); 30 f[i][1][1]=max(f[i-1][1][1],0)+a[i]; 31 f[i][2][0]=max(f[i-1][2][0],f[i-1][2][1]); 32 f[i][2][1]=max(f[i-1][1][0],max(f[i-1][1][1],f[i-1][2][1]))+a[i]; 33 } 34 ans=max(f[n][2][0],f[n][2][1]); 35 memset(f,128,sizeof(f)); 36 f[1][1][1]=a[1]; 37 for(int i=2;i<=n;i++) 38 { 39 f[i][1][0]=max(f[i-1][1][0],f[i-1][1][1]); 40 f[i][1][1]=f[i-1][1][1]+a[i]; 41 f[i][2][0]=max(f[i-1][2][0],f[i-1][2][1]); 42 f[i][2][1]=max(f[i-1][1][0],max(f[i-1][1][1],f[i-1][2][1]))+a[i]; 43 f[i][3][0]=max(f[i-1][3][0],f[i-1][3][1]); 44 f[i][3][1]=max(f[i-1][2][0],max(f[i-1][2][1],f[i-1][3][1]))+a[i]; 45 } 46 printf("%d",max(ans,f[n][3][1])); 47 }