• 【bzoj5427】最长上升子序列(贪心+LIS)


      题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5427

      因为noip,博客咕了好久,这几天集中填一下坑。

      这题我们可以假设往不确定的空位里填数,然后考虑一下如何尽可能让空位多被选上。我们发现,如果有一个空位没在最后的最长上升子序列里,那么可以贪心地去掉一个被选上的数再加上去。

      那么我们假定所有的空位都被选上。这样原序列就被划分成了许多段,而每一段内的在最长上升子序列里的数都必须与两边相差至少2(留一个数给空位)。那么我们可以把每一段数整体减去前面空位的数量(即每个数的数值减去前面没被确定的数的个数),然后直接跑一遍最长上升子序列,加上空位数量就行了。

      代码:

    #include<cstdio>
    #include<set>
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read(){int tmp=0; char c=nc(),f=1; for(;c<'0'||'9'<c;c=nc())if(c=='-')f=-1; for(;'0'<=c&&c<='9';c=nc())tmp=(tmp<<3)+(tmp<<1)+c-'0'; return tmp*f;}
    set<int>st;
    int n,k,delta=0;
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++){
            char ch=nc();
            while(ch<'A'||'Z'<ch)ch=nc();
            if(ch=='K'){
                k=read();
                set<int>::iterator iter=st.lower_bound(k-delta);
                if(iter==st.end())st.insert(k-delta);
                else if(*iter+delta>k)st.erase(iter),st.insert(k-delta);
            }
            else{
                ++delta;
                st.insert(-1000000000-delta);
            }
        }
        printf("%d
    ",st.size());
    }
    bzoj5427
  • 相关阅读:
    R中的一些数据形式
    R数据处理
    矩阵的一些知识
    R语言的一些矩阵运算
    R语言中的常用函数
    R读取数据和导出数据
    贝叶斯公式的理解方式
    R语言中bioconductor包
    R语言中的数据结构
    网页版的R设置环境变量
  • 原文地址:https://www.cnblogs.com/quzhizhou/p/10070606.html
Copyright © 2020-2023  润新知