【部分轉載】:【lower_bound、upperbound講解、二分查詢、最長上升子序列(LIS)、最長下降子序列模版】

KeepZ發表於2019-08-01

二分

lower_bound

lower_bound()在一個區間內進行二分查詢,返回第一個大於等於目標值的位置(地址)

upper_bound

upper_bound()與lower_bound()的主要區別在於前者返回第一個大於目標值的位置

int lowerBound(int x){
    int l=1,r=n;
    while(l<=r){
        int mid=(l+r)>>1;
        if (x>g[mid]) l=mid+1;
        else r=mid-1;
    }
    return l;
}
int upperBound(int x){
    int l=1,r=n;
    while(l<=r){
        int mid=(l+r)>>1;
        if (x>=g[mid]) l=mid+1;
        else r=mid-1;
    }
    return l;
}

最長上升子序列LIS

定義dp[i]為以i結尾的最長上升子序列長度,則dp[i]=max{0,d[j] | j<i && s[i]<s[j]}+1

最長上升子序列(>)相當於反序列的最長不上升子序列(<=)

int s[maxn],n;
int dp[maxn],g[maxn];
int main()
{
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++) scanf("%d",s+i);
        mem(g,0x3f);
        mem(dp,0);
        for(int i=0;i<n;i++){
            int k=lower_bound(g+1,g+n+1,s[i])-g;
            //int k=lowerBound(s[i]);
            dp[i]=k;
            g[k]=s[i];
        }
        int ans=-1;
        for(int i=0;i<n;i++) ans=max(ans,dp[i]);
        printf("%d\n",ans);
    }
    return 0;
}

================待更新==========

參考部落格1:https://blog.csdn.net/Martin20150405/article/details/51930912

參考部落格2:https://blog.csdn.net/wbin233/article/details/77570070

相關文章