• SCU 4441 Necklace


    最长上升子序列,枚举。

    因为$10000$最多只有$10$个,所以可以枚举采用哪一个$10000$,因为是一个环,所以每次枚举到一个$10000$,可以把这个移到最后,然后算从前往后的$LIS$和从后往前的$LIS$,然后枚举一下哪里断开就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    
    int a[100010],n;
    int b[100010],dp1[100010],dp2[100010];
    int c[40010],u,mx1[100010],mx2[100010];
    
    void get(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            u=max(u,c[rt]);
            return ;
        }
    
        int m = (l+r)/2;
        if(L<=m) get(L,R,l,m,2*rt);
        if(R>m) get(L,R,m+1,r,2*rt+1);
    }
    
    void update(int pos,int val,int l,int r,int rt)
    {
        if(l==r)
        {
            c[rt] = val;
            return ;
        }
    
        int m = (l+r)/2;
        if(pos<=m) update(pos,val,l,m,2*rt);
        if(pos>m) update(pos,val,m+1,r,2*rt+1);
    
        c[rt]=max(c[2*rt],c[2*rt+1]);
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    
            int ans=10000;
            for(int i=1;i<=n;i++)
            {
                if(a[i]!=10000) continue;
    
                for(int j=i+1;j<=n;j++) b[j-i]=a[j];
                for(int j=1;j<=i;j++) b[n-i+j]=a[j];
    
                for(int j=1;j<=n-1;j++) if(b[j]==10000) b[j]=0;
    
                memset(dp1,0,sizeof dp1);
                memset(dp2,0,sizeof dp2);
    
                memset(c,0,sizeof c);
                for(int j=1;j<=n-1;j++)
                {
                    u=0; get(b[j],10000,0,10000,1);
                    dp1[j] = u + b[j]; update(b[j],dp1[j],0,10000,1);
                }
    
                memset(c,0,sizeof c);
                for(int j=n-1;j>=1;j--)
                {
                    u=0; get(b[j],10000,0,10000,1);
                    dp2[j] = u + b[j]; update(b[j],dp2[j],0,10000,1);
                }
    
                for(int j=1;j<=n-1;j++) mx1[j]=max(mx1[j-1],dp1[j]);
                for(int j=n-1;j>=1;j--) mx2[j]=max(mx2[j+1],dp2[j]);
    
                for(int j=1;j<=n-1;j++)
                {
                    ans=max(ans,10000+dp1[j]);
                    ans=max(ans,10000+dp2[j]);
                }
    
                for(int j=1;j<=n-2;j++) ans=max(ans,10000+mx1[j]+mx2[j+1]);
            }
    
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Python常用模块——第三方开源模块的安装使用
    Python常用模块——模块介绍与导入
    Linux文本编辑器vim
    Linux文件和文件夹的操作
    网络编程之IO模型——selectors模块
    设计模式学习(19)- 中介者模式
    设计模式学习(18)- 迭代器模式
    设计模式学习(17)- 解释器模式
    设计模式学习(16)- 命令模式
    设计模式学习(15)- 责任链模式
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6648759.html
Copyright © 2020-2023  润新知