枚举10000所在位置然后,先预处理出来10000右边的情况,然后再处理左边,算法很好像,但是细节很繁琐,因为数组开小了wa了很多炮。。。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int n,tail,ans;
int c[20100],a[200100],dp[200100],sum[200100];
map<int,int>wei;
int lowbit(int x) {return x&(-x);}
int getmax(int x)
{
int now=0;
while (x>0)
{
now=max(now,c[x]);
x=x-lowbit(x);
}
return now;
}
void insert(int x,int z)
{
while (x<=20000)
{
c[x]=max(c[x],z);
x=x+lowbit(x);
}
}
void work(int x)
{
memset(sum,0,sizeof(sum));
memset(c,0,sizeof(c));
memset(dp,0,sizeof(dp));
for (int i=x;i<x+n;i++)
{
if (a[i]!=10000)
{
dp[i]=getmax(20000-a[i]+1)+a[i];
insert(20000-a[i]+1,dp[i]);
}
sum[i]=max(sum[i-1],dp[i]);
}
memset(c,0,sizeof(c));
memset(dp,0,sizeof(dp));
for (int i=x+n-1;i>=x;i--)
{
int tmp=i-n+1;
if (i-n+1<=0) tmp+=n;
if (a[tmp]!=10000)
{
dp[tmp]=getmax(20000-a[tmp]+1)+a[tmp];
insert(20000-a[tmp]+1,dp[tmp]);
}
ans=max(ans,dp[tmp]+sum[i]+10000);
}
}
int main()
{
freopen("test.in","r",stdin);
while (~scanf("%d",&n))
{
ans=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
for (int i=1;i<=n;i++)
if (a[i]==10000)
work(i);
printf("%d\n",ans);
}
return 0;
}