【DP】scu4441

来源:互联网 发布:长波电台事件 知乎 编辑:程序博客网 时间:2024/05/23 11:22
枚举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;}

0 0
原创粉丝点击