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; }