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;
}
posted on
浙公网安备 33010602011771号