JZOJ1728. Antimonotonicity
来源:互联网 发布:怎么给淘宝客服发图片 编辑:程序博客网 时间:2024/05/01 01:45
题目
Description
给你1-N的一个排列,数列中的数字互不相等,要求找出最长的子序列a,满足a1 > a2,a2 < a3,a3 > a4,a4 < a5……
Input
T 代表T组数据 T<=50
每组数据一行: n 代表给你n个数,然后就是n个数 N<=30000
Output
T行 每行一个数:
对于每组数据输出最长子序列的长度
Sample Input
4
5 1 2 3 4 5
5 5 4 3 2 1
5 5 1 4 2 3
5 2 4 1 3 5
Sample Output
1
2
5
3
分析
虽然是多组数据,其实没有什么影响,就把它当做一组数据就好了。
这里是求最长的上下波动的数列。感觉有点像求最长不下降子序列,看一下有没有什么启发?
- 显然这题应该用DP
因为题目要求的是上下不断改变的序列,所以很容易想到
设
那么
设
那么转移显然:
注意
fi,gi 所需要满足的条件。现在我们开始优化。
因为它们都要从大于或者小于它的状态转移过来,
所以,可以考虑排序。
如果在排序之后,那么我们只需要求[1..i] 和 [i..N] 这两个区间的
这里因为要区间查询,所以应该用线段树。
题解
先将它们拍一次序,记录每个数是原序列的第
根据
按照原序列的顺序来DP
每次利用线段树查询[1..i] 和 [i..N] 这两个区间的
更新
然后单点修改,将线段树的
枚举的复杂度是
那么总复杂度是
Code(C++)
#include <cstdio>#include <algorithm>#include <cstring>#include <string.h>#include <cmath>#include <stdlib.h>#include <math.h>using namespace std;struct arr{ int x,num,f;}a[30001];struct arr1{ int mf,mg,l,r;}tr[200000];int T,n,f[30001],g[30001],ans;bool cmp1(arr x,arr y){ return x.x<y.x;}bool cmp2(arr x,arr y){ return x.num<y.num;}int max(int x,int y){ if(x>y)return(x); return(y);}void make(int x,int l,int r){ tr[x].l=l; tr[x].r=r; tr[x].mg=tr[x].mf=0; if(l==r)return; int m=(l+r)/2; make(x+x,l,m); make(x+x+1,m+1,r);}void change1(int x,int y,int z){ if(tr[x].l==tr[x].r) { tr[x].mf=z; return; } if(y<=tr[x+x].r)change1(x+x,y,z); else change1(x+x+1,y,z); tr[x].mf=max(tr[x+x].mf,tr[x+x+1].mf); }void change2(int x,int y,int z){ if(tr[x].l==tr[x].r) { tr[x].mg=z; return; } if(y<=tr[x+x].r)change2(x+x,y,z); else change2(x+x+1,y,z); tr[x].mg=max(tr[x+x].mg,tr[x+x+1].mg);}int find1(int x,int l,int r){ if((tr[x].l==l)&&(tr[x].r==r))return tr[x].mf; if(r<=tr[x+x].r)return find1(x+x,l,r); else if(l>=tr[x+x+1].l)return find1(x+x+1,l,r); else return max(find1(x+x,l,tr[x+x].r),find1(x+x+1,tr[x+x+1].l,r));}int find2(int x,int l,int r){ if((tr[x].l==l)&&(tr[x].r==r))return tr[x].mg; if(r<=tr[x+x].r)return find2(x+x,l,r); else if(l>=tr[x+x+1].l)return find2(x+x+1,l,r); else return max(find2(x+x,l,tr[x+x].r),find2(x+x+1,tr[x+x+1].l,r));}int main(){ scanf("%d",&T); for(;T;T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i].x); a[i].num=i; } sort(a+1,a+1+n,cmp1); for(int i=1;i<=n;i++) a[i].f=i; make(1,1,n); sort(a+1,a+n+1,cmp2); memset(f,128,sizeof(f)); memset(g,128,sizeof(g)); f[1]=1; change1(1,a[1].f,1); ans=1; for(int i=2;i<=n;i++) { f[i]=find2(1,1,a[i].f)+1; g[i]=find1(1,a[i].f,n)+1; if(g[i]==1)g[i]=0; ans=max(ans,f[i]); ans=max(ans,g[i]); change1(1,a[i].f,f[i]); change2(1,a[i].f,g[i]); } printf("%d\n",ans); }}
- JZOJ1728. Antimonotonicity
- Antimonotonicity
- Antimonotonicity
- Antimonotonicity
- TJU Antimonotonicity
- poj 3298 Antimonotonicity DP
- Sicily 1448. Antimonotonicity
- poj 3298 Antimonotonicity 贪心
- Sicily 1448. Antimonotonicity
- JZOJ.1728. Antimonotonicity
- Antimonotonicity (Standard IO)
- ZCMU-1231-Antimonotonicity
- TOJ 2896.Antimonotonicity(贪心)
- 【BZOJ2795】[Poi2012]A Horrible Poem【Hash】【GCD】【暴力】
- 关于Iterator探究和思考
- a标签href中事javascript
- Ros学习之---URDF
- Window Pains-POJ2585
- JZOJ1728. Antimonotonicity
- iOS 刷新某个Section或Cell
- 点击按钮时软键盘消失
- 7.14.实验 解题参考
- git 常用基本用法
- 在往自己的Eclipse/MyEclipse中导外部Android项目的时候有时候会出现一些问题
- I/0事件驱动实现异步curl,一
- android 可签到的自定义日历控件
- 推箱子(双重bfs)