dp题目的优化
前言
今天做最长连续自序列的时候,发现有的时候dp:
现在我们有一个新元素a,对比dp的最后一个元素。如果 ,那么可以直接把a“接到” 的后面, 形成更长的上升子序列。即: ;
否则,找到dp中第一个大于等于a的元素,用a替换它 。这样替换后既保证仍形成上升子序列,又使得该上升子序列的最后元素更小。
但是这样做,无法记录路径。
例题
P1020 [NOIP1999 普及组] 导弹拦截
本题只需要找到最长非递增子序列和最长递增子序列即可,其中用到了lower_bound 和 upper_bound函数二分查找。这两个函数只能在升序序列中使用,所以在递减序列中查找时,需要修改一个小细节upper_bound(dp + 1, dp + sum + 1, a[i], greater<int>()) - dp 即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 20;
const int inf = 0x3f3f3f3f;
int a[maxn];
int dp[maxn];
int cnt = 0, tot = 0, sum = 0;
//O(nlogn)
int main() {
int num;
while (~scanf("%d", &num)) a[++ cnt] = num;
//最长非递增子序列
memset(dp, inf, sizeof(dp));
for (int i = 1; i <= cnt; i ++) {
if (a[i] <= dp[sum]) {
dp[++ sum] = a[i];
} else {
//只有在升序中才可以使用lower_bound 和 upper_bound
int t = upper_bound(dp + 1, dp + sum + 1, a[i], greater<int>()) - dp;
dp[t] = a[i];
}
}
cout << sum << "\n";
//最长上升子序列
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= cnt; i ++) {
if (a[i] > dp[tot]) dp[++ tot] = a[i];
else {
int t = lower_bound(dp + 1, dp + 1 + tot, a[i]) - dp;
dp[t] = a[i];
}
}
cout << tot << "\n";
return 0;
}
#504. 连续子序列
最长上升子序列的翻版,多了一个要求,就是子序列中的数字要连续,即相邻两个数的差值为1。由于子序列要求是连续的,所以每一个状态只能由比当前数小1的状态得来,根本不用暴搜,只要询问前一个值即可。a的范围是1e9,直接开数组空间会炸,用一个map就可以解决了。 参考博客
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define TLE std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int maxn = 2e5 + 10;
int a[maxn];
map<int, int> f;
int main() {
TLE;
int n;
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
}
int maxx = 0, flag ;
for(int i = 1; i <= n; i ++) {
f[a[i]] = f[a[i] - 1] + 1;
if(f[a[i]] > maxx) {
maxx = f[a[i]];
flag = a[i];
}
else if(f[a[i]] == maxx && a[i] < flag) flag = a[i];
}
cout << maxx << "\n";
for(int i = flag - maxx + 1; i <= flag; i ++) {
cout << i << " ";
}
cout << "\n";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!