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 2013-07-31 23:14  tobec  阅读(164)  评论(0编辑  收藏  举报