UVa1471 防线(DP,LIS优化)
程序员文章站
2022-03-12 17:59:56
...
本题要求在一个长度为n的序列中,删除一段连续子序列,使得剩下的序列有一个长度最大的连续递增子序列。
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define maxn 300000
#define inf 1e9+100
using namespace std;
typedef long long ll;
ll T,n,A[maxn],tmp,f[maxn],g[maxn],d[maxn],ans;
int main(){
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++) cin>>A[i];
//计算i结尾的最长长度 g[]
for(int i=1;i<=n;i++){
if(i==1) g[1]=1;
else if(A[i]>A[i-1]) g[i]=g[i-1]+1;
else g[i]=1;
}
//计算i开头的最长长度 f[]
for(int i=n;i>=1;i--){
if(i==n) f[i]=1;
else if(A[i]<A[i+1]) f[i]=f[i+1]+1;
else f[i]=1;
}
for(int i=1;i<=n;i++) d[i]=inf;
//solve,O(nlogn)
d[1]=A[1];
ans=1;
for(int i=2;i<=n;i++){
ll len=lower_bound(d+1,d+1+n,A[i])-d;
ans=max(ans,len-1+f[i]);
d[g[i]]=min(A[i],d[g[i]]);
}
cout<<ans<<endl;
}
return 0;
}
上一篇: 实验二 线性表综合实验之《静态链表》
下一篇: 学习Python的第一天(记录)