http://acm.hdu.edu.cn/showproblem.php?pid=4604
ans = max( 以i开头的最长不下降子序列+以i开头的最长不上升子序列-min(以i开头的最长不下降子序列中val[i]的个数,以i开头的最长不上升子序列中val[i]的个数) )
但是LIS求的是以i结尾的,所以将数组翻转
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> using namespace std; const int maxn = 100100; int val[maxn] , n; void DP(int num[],int dp[],int same[]) { vector <int> v; for(int i=0;i<n;i++) { int a , b; a = lower_bound(v.begin(),v.end(),num[i])-v.begin(); b = upper_bound(v.begin(),v.end(),num[i])-v.begin(); if(b == v.size()) { v.push_back(num[i]); dp[i] = v.size(); } else { v[b] = num[i]; dp[i] = b + 1; } same[i] = b - a + 1; } } int dp1[maxn],dp2[maxn],same1[maxn],same2[maxn]; int main() { int T; scanf("%d" , &T); while(T--) { scanf("%d" , &n); for(int i=0;i<n;i++) scanf("%d" ,&val[i]); reverse(val,val+n); DP(val,dp1,same1); for(int i=0;i<n;i++) val[i] = -val[i]; DP(val,dp2,same2); int ans = 0; for(int i=0;i<n;i++) ans = max(ans,dp1[i]+dp2[i]-min(same1[i],same2[i])); printf("%d\n" , ans); } return 0; }