HDU 1025 最大递增子序列长度

这道题目一开始我的是复杂度为 n^2的DP,发现超时了,于是去学了,

nlgn的DP+二分的方法,一开始样例过了,我还以为自己写对了,后来

交上去却WA了,原来对这个还是理解不是太深,写起来有个地方没有理解清楚

后来慢慢看懂了!!!!

其实这个原理很简单,就是先比较一头一尾,然后进行二分,找到其中第一个比他大的数,然后拿这个数

替换掉那个比他大的数,一直进行这样,时间就会减少!!!!


代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=500005;
int a[maxn],f[maxn];
int n;

int bsearch(int* f,int x,int& a) {
    int left=1;
    int right=x;
    while(left<=right) {
        int mid=(left+right)>>1;
        if(f[mid-1]<a&&a<=f[mid])return mid;
        else if(a>f[mid])left=mid+1;
        else right=mid-1;
    }
}

int LIS(int* a,int n) {
    int size=2;
    f[1]=a[1];
    int j=1;
    for(int i=2; i<=n; i++) {
        if(a[i]<=f[1]) {//一开始这里写错了,其实很好理解的,就是先去一头一尾进行判断,然后对中间的进行二分
            j=1;
        } else if(a[i]>=f[size-1]) j=size++;
        else j=bsearch(f,size,a[i]);
        f[j]=a[i];
    }
    return size-1;
}



int main() {
    int tcase=0;
    while(scanf("%d",&n)!=EOF) {
        memset(a,0,sizeof(a));
        for(int i=1; i<=n; i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            a[x]=y;
        }
        int ans;
        ans=LIS(a,n);
        printf("Case %d:\n",++tcase);
        if(ans<=1) {
            printf("My king, at most %d road can be built.\n\n",ans);
        } else {
            printf("My king, at most %d roads can be built.\n\n",ans);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值