15-最长上升子序列(二分)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[100005], c[100005];

int find(int low, int high, int x){
    while(low < high){
        int mid = (high + low) / 2;
        if(x < c[mid])
            high = mid;
        else
            low = mid + 1;
    }
    return low;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(a, 0, sizeof(a));
        memset(c, 0, sizeof(c));
        for(int i = 0; i < n; i++)    
            scanf("%d", &a[i]);
        int len = 0;
        c[0] = a[0];
        for(int i = 1; i < n; i++){
            if(a[i] > c[len]){
                c[++len] = a[i];
            }
            else{
                int w = find(0, len, a[i]);
                c[w] = a[i];
            }
        }    
        printf("%d\n", len + 1);
    }
    return 0;
}

时间: 2024-10-11 17:54:25

15-最长上升子序列(二分)的相关文章

【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间),使得剩余的数最长上升子序列(LIS)最长. 题目思路: [二分][最长上升子序列] 首先,假设去掉[i,i+m-1]这L个数,剩余的LIS长度为max(i左端最后一个不大于a[i+m]的LIS长度+a[i+m]开始到最后的LIS长度). 所以,我们从n到1逆向先求最长下降子序列的长度f[i],就可以知

【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码

题目链接: https://vijos.org/p/1028 题目大意: 给N个字符串(N<=2000),求能组成词链的单词最多有几个. 如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含 即前一个单词是后一个单词的前缀,则称词表为一个词链.例如下面单词组成了一个词链: i int integer 但下面的单词不组成词链: integer intern 题目思路: [动态规划][二分][最长上升子序列] 二分查找最长可达的长度. 1 // 2 //by co

【最长下降子序列】【动态规划】【二分】XMU 1041 Sequence

题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1041 题目大意: 一个二维平面,上面n(n<=1 000 000)个点.问至少选多少个点才能完全包含所有的点. 包含是指xy坐标均不大于. 题目思路: [最长下降子序列][动态规划][二分] 这题n有107,所以用二分做最长下降子序列. 首先将所有点按x坐标或者y坐标排序,保证一维的单调性. 之后在剩余一维的数中求最长严格下降子序列即可. (如果下一个点是上升的那么可以放弃当前的点转

POJ-2533最长上升子序列(DP+二分)(优化版)

Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Accepted: 18453 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ...

最长上升子序列的二分优化

http://blog.csdn.net/wall_f/article/details/8295812 作者写的太好了,转载一下~ 我简单总结一下,我的理解. 最长上升子序列的转移方程:b[k]=max(max(b[j]|a[j]<a[k],j<k)+1,1); 其优化主要在求解当前最长长度是要查找前面的b数组中是否有最大的值,且当前期a[j]<a[k],因此就是要找小于当前值的最大值. 所以我们一般需要从1~k-1扫描一遍找到最大值,复杂度为o(n^2),耗时太长. 因此我们可以直接记

【动态规划】【二分】CDOJ1006 最长上升子序列

最长上升子序列. 要求输出字典序最小解. 就在更新答案的时候记录一下前驱.容易发现记录的这个玩意实际上形成了一个森林. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int T,n,a[1010],b[1010],pre[1010],anss[1010],e,pos[1010]; int main(){ int x; scanf("%d",&am

[CLRS][CH 15.4] 最长公共子序列

---恢复内容开始--- 摘要 介绍了最长公共子序列的概念及解题思路. 子序列概念 子序列:一个给定序列的子序列就是该给定序列中,去掉零个或多个元素.一般来说,给定一个序列 X = <x1, x2, ..., xm>,另一个序列 Z = <z1, z2, ..., zk> 如果存在X的一个严格递增下标序列<i1, i2, ..., ik>,使得所有的j = 1, 2, ..., k,有xij = zj,则Z是X的一个子序列.例如,Z = <B, C, D, B&g

UVA 10534 Wavio Sequence(二分 + 最长上升子序列)

Wavio Sequence 题目: 题目大意: 题目是给一个序列,然后再其序列中找一个子序列,这个子序列符合前一半是递增的序列,后半部分是递减的序列,并且是这个序列中所有符合条件的子序列中最长的,输出其长度. 思路分析: 题目读懂以后,解法就迎刃而出了,很显然,正着求一个最长上升子序列,倒着求一个最长上升子序列.然后从这两个序列中找重合的位置最符合题意的,不过在这道题中,需要标记到每一位的最长上升子序列,因为每一位都可能成为符合题意的子序列的中间那一位置.这就需要用两个数组来标记,一个标记正方

[DP][二分]JZOJ 3467 最长上升子序列

Description 维护一个序列,使它可以进行下面两种操作: 1.在末尾添加一个数字x 2.将整个序列变成第x次操作后的样子 在每次操作后,输出当前序列的最长上升子序列的长度 序列初始时为空 Input 输入文件lis.in的第一行有一个正整数n,表示操作个数.接下来n行每行有两个整数op,x.如果op为0,则表示添加x这个数字:如果op为1,则表示回到第x次操作之后. Output 对于每次操作,在输出文件lis.out中输出一个答案,表示当前最长上升子序列的长度 Sample Input

LIS:最长上升子序列

学习动态规划问题(DP问题)中,其中有一个知识点叫最长上升子序列(longest  increasing subsequence),也可以叫最长非降序子序列,简称LIS.简单说一下自己的心得.(大神可无视..) 我们都知道,动态规划的一个特点就是当前解可以由上一个阶段的解推出, 由此,把我们要求的问题简化成一个更小的子问题.子问题具有相同的求解方式,只不过是规模小了而已.最长上升子序列就符合这一特性.我们要求n个数的最长上升子序列,可以求前n-1个数的最长上升子序列,再跟第n个数进行判断.求前n