最长上升子序列

最长不下降子序列:

普通的动态规划就是以f[i]表示第I个作为序列尾数的最长序列长度。然后确定状态转移方程,如果前I-1个有小于第I个数的数a[j],找出其中最大的那个数,然后f[I]=f[j]+1,否则

f[i]=1。这样由于序列是无序的,时间复杂度为O(n*2).

优化就是建一个数组A,使得A[len]=a[j],表示长度为len的上升子序列的最小末尾数。由于A[]是有序的,那么在查找的时候可以二分,总时间复杂度就是O(nlgn).

代码如下:

#include<stdio.h>
int a[1000],A[1000];
int search(int r,int target){
    int l,mid;
    l=0;
    while(l<r){
        mid=(l+r)/2;
        if(A[mid]<target)
            l=mid+1;
        else
            r=mid;
    }
    return l;
}
int main(){
    int N,i,ans;
    scanf("%d",&N);
    for(i=0;i<N;i++)
        scanf("%d",&a[i]);
    ans=1;
    A[1]=a[0];
    for(i=1;i<N;i++){
        if(A[ans]<a[i])
            A[++ans]=a[i];
        else
            A[search(ans,a[i])]=a[i];
    }
    printf("%d\n",ans);
    return 0;
}


同类问题:

1.给n条线段的左右短点坐标值,求最多多少条线段是覆盖的(Ural 1078)

2.要邀请n个人参加party,每个人有力量值strength Si和魅力值 beauty Bi,如果存在两人S i ≤ Sj and B i ≥ Bj 或者  S i ≥ Sj and B i ≤ Bj 他们两个会产生冲突,问在不产生冲突的条件下,最多能邀请到几个人?

这个题有两个关键字,要保证(Si<Sj&&Bi<Bj)先按Si升序保证Si不同的人是严格上升的,然后Si相同按Bi降序,保证相同Si的人冲突(即如果Bi上升必定属于不同的Si),此时转换为了求S的最长上升子序列的问题。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值