http://acm.hdu.edu.cn/showproblem.php?pid=4604

将原数组根据其大小关系处理后 使其大小全在10^5内

处理后为 a1,a2,a3.....an

最优deque   b1,b2,b3....bm

先不考虑有相等的情况

假设bj在数组a中出现的最早 对应到a数组中为ai

那么从bj到bm为  以ai为起点到an的最长递增序列(必须包括ai) 用(ai,L)表示

以及从bj到b1为  以ai为起点到an的最长递减序列(必须包括ai)  用(ai,R)表示

但这样没有考虑b中有相等的情况 不过思路有了 剩下处理相等既可以了

把(ai,L)改为非递减  把(ai,R)改为非递增 最后把重复加的减掉 这样又会出错 比如说 a(1,1,2,1,1)

所以在把(ai,L)改为非递减  把(ai,R)改为非递增后    要枚举(ai,L)+(以一个比ai小的数为端点,R) 和 (以一个比ai大的数为端点,L)+(ai,R) 两种情况

其中 一个比ai大/小的数 是在ai之后的数 要求是所以满足要求的数中使( ,L)/( ,R)最大的那个

剩下的是DP思想  需要用线段树优化(其它优化也可)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#include<queue>
#include<stdexcept>
#include<bitset>
#include<cassert>
#include<deque>
#include<numeric>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
const double eps=1e-12;
const int INF=0x3f3f3f3f;
const ll MOD=1000000007;
const int N=100005;
struct node
{
    int l,r,L,R;
}tree[N*4];
int num[N];
int a[N],b[N];
map<int,int>mt;
void dfsb(int x,int l,int r)
{
    tree[x].l=l;
    tree[x].r=r;
    tree[x].L=0;
    tree[x].R=0;
    if(l==r) return ;
    int mid=(l+r)>>1;
    dfsb((x<<1),l,mid);
    dfsb((x<<1)|1,mid+1,r);
}
void dfsm(int x,int l,int r,int &L,int &R)
{
    if(l>r) return;
    if(tree[x].l==l&&tree[x].r==r)
    {
        L=max(tree[x].L,L);
        R=max(tree[x].R,R);
        return ;
    }
    int mid=(tree[x].l+tree[x].r)>>1;
    if(r<=mid)
    dfsm((x<<1),l,r,L,R);
    else if(l>mid)
    dfsm((x<<1)|1,l,r,L,R);
    else
    {
        dfsm((x<<1),l,mid,L,R);
        dfsm((x<<1)|1,mid+1,r,L,R);
    }
}
void dfsu(int x,int k,int L,int R)
{
    tree[x].L=max(tree[x].L,L);
    tree[x].R=max(tree[x].R,R);
    if(tree[x].l==tree[x].r)
    return ;
    int mid=(tree[x].l+tree[x].r)>>1;
    if(k<=mid)
    dfsu((x<<1),k,L,R);
    else
    dfsu((x<<1)|1,k,L,R);
}
int solve(int *a,int n)
{
    memset(num,0,sizeof(num));
    int ans=0;
    dfsb(1,1,n);
    for(int i=n-1;i>=0;--i)
    {
        int k=a[i];
        int L=0,R=0;
        L=0;
        dfsm(1,1,k,L,R);
        int s1=L+1;
        L=0;
        dfsm(1,1,k-1,L,R);
        int r1=L;
        R=0;
        dfsm(1,k,n,L,R);
        int s2=R+1;
        R=0;
        dfsm(1,k+1,n,L,R);
        int r2=R;
        ++num[k];
        ans=max(ans,max(s1+r2,s2+r1));
        dfsu(1,k,s1,s2);
    }
    return ans;
}
int main()
{
    //freopen("data.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
       int n;
       scanf("%d",&n);
       for(int i=0;i<n;++i)
       {
           scanf("%d",&a[i]);
           b[i]=a[i];
       }
       mt.clear();
       sort(b,b+n);
       int l=0;
       for(int i=0;i<n;++i)
       {
           if(i==0||b[i]!=b[i-1])
           b[l++]=b[i];
       }
       int ln=l;
       for(int i=0;i<ln;++i)
       mt[b[i]]=i+1;
       for(int i=0;i<n;++i)
       a[i]=mt[a[i]];
       printf("%d\n",solve(a,n));
    }
    return 0;
}

 

 

posted on 2013-07-23 23:41  夜->  阅读(186)  评论(0编辑  收藏  举报