题目大意:求一个序列中 先严格递增后严格递减的子序列的数目(要求这个子序列对称)。
题目思路:正一遍DP,反一遍DP,因为n<=1e5,dp要把时间压缩到nlogn
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #define MAXSIZE 100005 using namespace std; int dp[MAXSIZE],a[MAXSIZE]; int n; int Solve() { dp[1] = 1; int G1[MAXSIZE],G2[MAXSIZE],len=1,pos; G1[1] = a[1]; for(int i=2;i<=n;i++) { if(a[i] > G1[len]) pos = ++len; else { pos = lower_bound(G1+1,G1+1+len,a[i]) - (G1+1) + 1; } G1[pos] = a[i]; dp[i] = len; } G2[1] = a[n]; len = 1; int ans = 1; for(int i=n-1;i>=1;i--) { if(a[i] > G2[len]) pos = ++len; else pos = lower_bound(G2+1,G2+1+len,a[i]) - (G2+1) + 1; G2[pos] = a[i]; int temp = min(len,dp[i]); ans = max(ans,temp); } return 2*ans - 1; } int main() { int T,cns=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int ans =Solve(); printf("Case %d: %d ",cns++,ans); } return 0; }