LIS最长上升子序列三种方法

来源:互联网 发布:linux 中文方格 编辑:程序博客网 时间:2024/06/06 09:16

O(n^2)的方法:

#include <iostream>

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
int a[15010],dp[15010],front[15010];
int n;
int main()
{
    scanf("%d",&n);
    int maxn=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        dp[i]=1;
        front[i]=-1;
        for(int j=1;j<i;j++){
            if(a[j]<a[i]){
                dp[i]=max(dp[i],dp[j]+1);
                front[i]=j;
            }
        }
        maxn=max(maxn,dp[i]);
    }
    cout<<maxn<<endl;
    return 0;

}

O(n log n)的方法:

二分:

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
int n,a[20010],c[20010],len=0;
int Find(int x)
{
    int l=1,r=len,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(x>c[mid]){ //记忆方法:求上升序列,就表示x更大,那么就是大于
            l=mid+1;
        }else r=mid-1;
    }
    return l;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        int k=Find(a[i]);
        c[k]=a[i];
        len=max(len,k);
    }
    printf("%d",len);
    return 0;
}

STL 求最长上升子序列:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 1000
#define INF 2^32-1
int n;
int a[N],dp[N];
void solve()
{
    fill(dp,dp+n,INF);
    for(int i=0;i<n;i++)
        *lower_bound(dp,dp+n,a[i])=a[i];
    printf("%d\n",lower_bound(dp,dp+n,INF)-dp);
}
int main()
{
    while(cin>>n){
        for(int i=0;i<n;i++)
            cin>>a[i];
        solve();
    }
    return 0;
}

原创粉丝点击