Processing math: 100%

最长上升子序列

最长上升子序列

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

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

定理:如果当前已选子序列的最后一位ans[last]有更合适的选择,则该选择a[i]满足ans[last1]<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;//找到第一个比a[i]大的数 
            lis[pos] = a[i];
        }
    }
    for(int i = 1; i <= len; i++) cout<<lis[i]<<" ";
    cout<<endl;
    cout<<len; 
    return 0; 
}
posted @   DAGGGGGGGGGGGG  阅读(196)  评论(0编辑  收藏  举报
编辑推荐:
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
阅读排行:
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析
点击右上角即可分享
微信分享提示