求最长上升子序列(二分)

upper_bound 和 lower_bound 的讲解 

 

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
const int maxn =300003, INF = 0x7f7f7f7f;
int low[maxn], a[maxn];
int n, ans;
int main()
{
    scanf("%d", &n);
    for(int i=1; i<=n; i++) 
    {
        scanf("%d", &a[i]); 
        low[i] = INF;   //由于low中存的是最小值,所以low初始化为INF 
    }
    low[1] = a[1]; 
    ans = 1;   //初始时LIS长度为1 
    for(int i=2; i<=n; i++)
    {
        if(a[i] > low[ans])    //若a[i]>=low[ans],直接把a[i]接到后面 
            low[++ans] = a[i];
        else       //否则,找到low中第一个>=a[i]的位置low[j],用a[i]更新low[j] 
            low[lower_bound(low+1, low+ans+1, a[i])-low] = a[i];
    }
    printf("%d\n", ans);   //输出答案 
    return 0;
}

 

求最长上升子序列(二分)_第1张图片

你可能感兴趣的:(算法)