A1926 登山
正倒序求最长上升子序列,枚举拐点即可。
这里采取二分写法。
#include<bits/stdc++.h>
using namespace std;
const int N=1009,inf=1e9;
int k[N],unum[N],dnum[N],ulen[N],dlen[N],ucnt,dcnt,ans,n;
int main(){
scanf("%d",&n),unum[0]=dnum[0]=-inf;
for(int i=1;i<=n;i++)
unum[i]=dnum[i]=inf;
for(int i=1;i<=n;i++){
scanf("%d",&k[i]);
ulen[i]=(lower_bound(unum,unum+ucnt+1,k[i])-unum);
unum[ulen[i]]=min(unum[ulen[i]],k[i]);
ucnt=max(ucnt,ulen[i]);
}
for(int i=n;i>=1;i--){
dlen[i]=(lower_bound(dnum,dnum+dcnt+1,k[i])-dnum);
dnum[dlen[i]]=min(dnum[dlen[i]],k[i]);
dcnt=max(dcnt,dlen[i]);
ans=max(dlen[i]+ulen[i]-1,ans);
}
// for(int i=1;i<=n;i++)
// printf("%d:%d %d\n",i,ulen[i],dlen[i]);
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号