题解:P11187 配对序列
大家好,我非常喜欢线段树优化 dp,于是我使用线段树优化 dp 通过了这道题目。
前排提醒:本题解做法时间复杂度带一只
Solution P11187
Idea
不难发现配对序列就是形如
我们设
显然有:
解释一下:如果这个数是第偶数个位置,它前面一个必须是它自己。如果是第奇数个位置,只要前一个位置不是它自己都可以转移。另外,
这样的复杂度是
考虑优化。
我们发现后面转移
求区间最大值,不难联想到线段树。
这样我们把
最后答案显然是
这样复杂度就是只带一只
Code
代码中的
#include<bits/stdc++.h>
#define ls now<<1
#define rs (now<<1)|1
using namespace std;
const int N=500005;
int dp[N],tr[N<<2],n,a[N];
void add(int l,int r,int p,int now,int x){
if(l==r&&l==p){
tr[now]=max(tr[now],x);
return;
}
int mid=(l+r)>>1;
if(p<=mid)add(l,mid,p,ls,x);
else add(mid+1,r,p,rs,x);
tr[now]=max(tr[ls],tr[rs]);
}
int query(int l,int r,int al,int ar,int now){
if(al>ar)return 0;
if(al<=l&&r<=ar)return tr[now];
int mid=(l+r)>>1,res=0;
if(al<=mid)res=max(res,query(l,mid,al,ar,ls));
if(ar>mid)res=max(res,query(mid+1,r,al,ar,rs));
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
if(dp[a[i]]!=0)add(1,500000,a[i],1,dp[a[i]]+1);
int res=max(query(1,500000,1,a[i]-1,1),query(1,500000,a[i]+1,500000,1));
dp[a[i]]=res+1;
}
printf("%d",tr[1]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】