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;
}
posted @ 2026-02-04 12:06  2025ing  阅读(0)  评论(0)    收藏  举报