码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-12-05 14:27:47      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:序列   style   php   get   opened   nbsp   code   个数   ==   

  题目传送门: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\n",st.size());
}
bzoj5427

 

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

标签:序列   style   php   get   opened   nbsp   code   个数   ==   

原文地址:https://www.cnblogs.com/quzhizhou/p/10070606.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!