首页 > 其他 > 详细

最长上升子序列

时间:2019-07-17 20:36:49      阅读:89      评论:0      收藏:0      [点我收藏+]

最长上升子序列

最长上升子序列是DP的入门题目,解法多样,只介绍\(nlog_n\)的做法。

其实nlogn的做法不是传统的DP而是贪心。

定理:如果当前已选子序列的最后一位ans[last]有更合适的选择,则该选择a[i]满足\(ans[last - 1]< a[i] < ans[last]\),所以可以用二分优化查找,来更新已选子序列。

/*#include <bits/stdc++.h>
using namespace std;
int n, data[100010], dp[1001000];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &data[i]), dp[i] = 2147483647;
    for (int i = 1; i <= n; i++)
        *lower_bound(dp + 1, dp + 1 + n, data[i]) = data[i];
    printf("%d", lower_bound(dp + 1, dp + 1 + n, 2147483647) - (dp + 1));
    return 0;
}   
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100100;
int a[maxn], n, lis[maxn], len;
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>a[i];
    lis[++len] = a[1];
    for(int i = 2; i <= n; i++)
    {
        if(a[i] > lis[len])
            lis[++len] = a[i];
        if (a[i] < lis[len])
        {
            int pos = lower_bound(lis+1, lis+1+len, a[i]) - lis;//找到第一个比pos 
            lis[pos] = a[i];
        }
    }
    for(int i = 1; i <= len; i++) cout<<lis[i]<<" ";
    cout<<endl;
    cout<<len; 
    return 0; 
}

最长上升子序列

原文:https://www.cnblogs.com/liuwenyao/p/11203425.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!