此题的大意是给定一个序列,求一个最长的奇数子序列,使得前k个序列上升,后k个序列下降。
此题的解法是从左往右求一次最长上升子序列,然后从右往左再求一次最长上升子序列,分别记录在状态变量d1[i],d2[i],求min(d1[i],d2[i])的最大值即可,答案就是2*min-1。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> using namespace std; #define MAXN 10010 #define INF 1000000000 int seq[MAXN]; int d1[MAXN],d2[MAXN]; int g[MAXN]; int main() { int n; while(scanf("%d",&n)==1) { for(int i=1;i<=n;i++)scanf("%d",&seq[i]); for(int i=1;i<=n;i++)g[i]=INF; memset(d1,0,sizeof(d1)); for(int i=1;i<=n;i++) { int k=lower_bound(g+1,g+1+n,seq[i])-g; d1[i]=k; g[k]=seq[i]; } for(int i=1;i<=n;i++)g[i]=INF; memset(d2,0,sizeof(d2)); for(int i=n;i>=1;i--) { int k=lower_bound(g+1,g+1+n,seq[i])-g; d2[i]=k; g[k]=seq[i]; } int ans=0; for(int i=1;i<=n;i++) { ans=max(ans,min(d1[i],d2[i])); } cout<<2*ans-1<<endl; } }