LIS n^2&nlogn模板

LIS nlogn模板 http://acm.hdu.edu.cn/showproblem.php?pid=1950

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <stdlib.h>
#define maxn 40000+10
using namespace std;
int a[maxn],d[maxn],len;
int bs(int i){
    int l,r,mid;
    l=0,r=len;
    while(l<r){
        mid=(l+r)/2;
        if(d[mid]>=a[i])r=mid;
        else l=mid+1;
    }
    return l;
}
int main(){
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        d[1]=a[1];
        len=1;
        for(int i=2;i<=n;i++){
            if(a[i]>d[len])
                d[++len]=a[i];
            else{
                int pos=lower_bound(d,d+len,a[i])-d;
                d[pos]=a[i];//找到>=a[i]的并更新
            }
        }
        printf("%d\n",len);
    }
    return 0;
}

LIS n^2模板  http://poj.org/problem?id=2533

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#define INF 0x3f3f3f3f
#define maxn 10000+10
using namespace std;
int a[maxn],n,dp[maxn];
int main()
{
    while(cin>>n){
        int len=-1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        dp[0]=-INF;
        for(int i=1;i<=n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(a[i]>a[j])//满足条件时
                    dp[i]=max(dp[i],dp[j]+1);
                if(dp[i]>len)len=dp[i];
            }
        }
        printf("%d\n",len);
    }
    return 0;
}
时间: 2024-08-03 21:26:22

LIS n^2&nlogn模板的相关文章

uva 10635 Prince and Princess(LCS问题转化成LIS问题O(nlogn))

题目大意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 分析:本题是LCS问题,但是p*q<=62500,O(pq)的算法显然会LE.在这里有一个条件,每个序列中的各个元素互不相同,所以可以把A中元素重新编号为1~p+1.例如,样例中A={1,7,5,4,8,3,9},B={1,4,3,5,6,2,8,9},因此把A重新编号为{1,2,3,4,5,6,7},则B就是{1,4,6,3,0

bzoj1264 基因匹配Match (lcs转lis lcs(nlogn))

基因匹配Match 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目描述 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成 DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成,那么它的长度一定是5N. 卡卡醒来后向可可叙述了这个奇怪的梦,而可 可这些日子正在研究生物信息学中的基因匹配问题,于是他决定为这个奇怪星球上的生物写一个简单

最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现

关于最长递增子序列时间复杂度O(n^2)的实现方法在博客http://blog.csdn.net/iniegang/article/details/47379873(最长递增子序列 Java实现)中已经做了实现,但是这种方法时间复杂度太高,查阅相关资料后我发现有人提出的算法可以将时间复杂度降低为O(nlogn),这种算法的核心思想就是替换(二分法替换),以下为我对这中算法的理解: 假设随机生成的一个具有10个元素的数组arrayIn[1-10]如[2, 3, 3, 4, 7, 3, 1, 6,

LIS O(n^2)模板

dp[j] = max(dp[k]+1,dp[j])(0<k<j&a[j]>a[k]) #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <stack> #include <queue> #include <algorithm> using namespace std; const

最长上升子序列O(nlogn)模板

#include<iostream> #include<stdio.h> using namespace std; const int MAXN=500010; int a[MAXN],b[MAXN]; //b[k]是序列a中所有长度为k的递增子序列中的最小结尾元素值 //用二分查找的方法找到一个位置,使得num>b[i-1]并且num<b[i],并用num代替b[i] int Search(int num,int low,int high){ int mid; whi

What Goes Up UVA - 481 LIS+打印路径 【模板】

打印严格上升子序列: #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<qu

LIS(nlogn) POJ 3903 Stock Exchange

题目传送门 1 /* 2 最长递增子序列O(nlogn)算法: 3 设当前最长递增子序列为len,考虑元素a[i]; 4 若d[len]<a[i],则len++,并将d[len]=a[i]; 5 否则,在d[1~len]中二分查找,找到第一个比它小的元素d[j],并d[j]=a[i]. 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <iostream> 10 #include <algori

BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS &amp; LDS (nlogn)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1609 题意: 给你一个只由数字"1,2,3"组成的序列a[i],共n个数. 你可以任意更改这些数字,使得序列中每一种数字都"站在一起",并且单调不减或不增. 例如:"1111222", "332211"... 问你至少更改多少个数字. 题解: 单调不减:求原序列LIS(最长非降子序列),当前答案t1 = n - LIS

关于LIS和LCS问题的o(nlogn)解法

o(n^2)解法就不赘述了,直接解释o(nlogn)解法 LIS最长递增子序列: 先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列.也即认为,长度为len的递增子序列中末尾元素最小的那种最需要保留.我们不妨称这个目前找到序列为到目前为止的 最优序列. 因此设置一个数组lis[i]其中 i 表示此时最大递增序列的长度,数组值表示此时达到 i 的最优序列(也即 长度为len的递增子序列中末尾元素最小的那种)的末尾元素. 那么此时只