最长上升子序列模板(二分优化)

普通的板子

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cassert>
#include <complex>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <numeric>
#include <sstream>
#include <ctime>
#include <cctype>
#include <set>
#include <map>
#include <queue>
#include <bitset>
#include <deque>
#include <stack>
#include <memory.h>
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int a[10005];
int n;
int LCS()
{
    int dp[60];
    memset(dp,0,sizeof(dp));
    dp[0] = 1;
    int ans = 1;
    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);
            }
        }
        ans = max(dp[i], ans);
    }
    return ans;
}

int mian()
{

    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    int ans=LCS();
    printf("%d\n",ans);
    return 0;
}



二分优化后的板子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int MAX=50000;
using namespace std;
int arr[MAX+50],ans[MAX+50],len;
int binary_search(int i)//手写二分法
{
    int left,right,mid;
    left=0,right=len;
    while(left<right)
    {
        mid = left+(right-left)/2;
        if(ans[mid]>=arr[i]) right=mid;
        else left=mid+1;
    }
    return left;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>arr[i];
    ans[0] = arr[1];
    len=0;
    for(int i=2; i<=n; i++)
    {
        if(arr[i]>ans[len])
            ans[++len]=arr[i];
        else
        {
            int pos=binary_search(i);
            //int pos=lower_bound(ans,ans+len,arr[i])-ans;//也可直接使用STL库里的函数
            ans[pos] = min(ans[pos],arr[i]);
        }
    }

    cout<<len+1<<endl;//数组大小就是最长上升子序列的个数

}

猜你喜欢

转载自blog.csdn.net/qq_41021816/article/details/82956442