记录一下各种dp的优化
A. 最长上升子序列
时间限制:1000 ms内存限制:128 MB类型:传统评测:文本比较上传者: sysulby
题目描述
(LIS问题)给定一个序列,从中选取若干个数,使得这一组数组成上升子序列尽可能长,即对于所有的 满足 ,求这个序列的最长上升子序列的长度。
输入格式
第一行一个整数 表示序列的长度
接下来一行 个整数表示序列
输出格式
一行一个整数表示最长上升子序列的长度
样例
样例输入复制
5
1 5 1 2 4
样例输出复制
3
数据范围与提示
组成的数列为 ,不存在比这个更长的上升子序列
-
对于 的数据,
-
对于 的数据,
二分优化
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000050],q[1000050],f[1000050],ans;
int main(){
cin>>n;
memset(q,0x3f,sizeof(q));
for(int i = 1;i <= n;i++)cin>>a[i];
for(int i = 1;i <= n;i++){
int j = lower_bound(q+1,q+n+1,a[i])-q;
j--;
f[i] = j+1;
ans = max(ans,f[i]);
if(a[i]<q[f[i]]) q[f[i]] =a[i];
}
cout<<ans;
return 0;
}
树状数组优化
#include<bits/stdc++.h>
using namespace std;
const int N = 1000000+1;
int a[N],b[N],nn;
int t[N];
int n,q;
int lowbit(int x){
return x & (-x);
}
void add(int i ,int x){
for(;i <= N;i+=lowbit(i)){
t[i]=max(t[i],x);
}
}
int getsum(int i){
int sum = 0;
for(;i >0;i -=lowbit(i))sum = max(sum,t[i]);
return sum;
}
map<int,int> pm;
int cnt;
int main(){
int n;
cin>>n;
for(int i = 1;i <= n;i++){
cin>>a[i];
b[i] = a[i];
}
int res = 0;
sort(b + 1, b + 1 + n);
for(int i = 1;i <= n;i++){
if(i == 1||b[i]!= b[i-1]){
pm[b[i]] = ++cnt;
}
}
for(int i = 1;i <= n;i++){
int maxn = getsum(pm[a[i]]-1)+1;
res = max(res,maxn);

本文介绍了动态规划在多种IT技术问题中的应用,如最长上升子序列、烽火传递中的信号优化、逆序对数列计数、滑动窗口问题以及修剪草坪的奶牛调度,展示了使用二分、树状数组、集合和单调队列等方法进行优化的实例。
最低0.47元/天 解锁文章
1748





