最长上升子序列
最长上升子序列
最长上升子序列是DP的入门题目,解法多样,只介绍nlogn的做法。
其实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;//找到第一个比a[i]大的数
lis[pos] = a[i];
}
}
for(int i = 1; i <= len; i++) cout<<lis[i]<<" ";
cout<<endl;
cout<<len;
return 0;
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析