[codevs3289]花匠 线段树优化dp
来源:互联网 发布:mac图片如何新建文件夹 编辑:程序博客网 时间:2024/05/20 06:41
题目←
大意:
求最长波动序列
设f[i]为dp到第i位、以波峰结尾的最长波动序列,
设g[i]为dp到第j位、以波谷结尾的最长波动序列。
则f[i]可以由满足h[j] < h[i]的g[j]转来,
g[i]可以由满足h[j] > h[i]的f[j]转来。
则当转移f[i]的时候,需要找到之前出现过的、高度小于h[i]的且g[j]最大的点
用h[i]的值域建树,maxf/maxg[h[i]]表示以高度h[i]结尾的最大f[i]/g[i]
每获得一个新的f[i]或g[i],更新maxf/maxg[h[i]]。
那转移f[i]的时候,询问(0,h[i] - 1)区间中最大的maxg就可以了。
#include<iostream>#include<cstdio>#include<algorithm>#define L(w) w << 1#define R(w) w << 1|1#define INF 1061109567using namespace std;const int MAXN = 200000 + 50;int L[MAXN << 2],R[MAXN << 2],maxf[MAXN << 2],maxg[MAXN << 2];int n,h[MAXN],maxn;void update(int w){ maxf[w] = max(maxf[L(w)],maxf[R(w)]); maxg[w] = max(maxg[L(w)],maxg[R(w)]);}void build_tree(int w,int l,int r){ L[w] = l;R[w] = r; if(l == r) { maxf[w] = -INF; maxg[w] = -INF; return; } int mid = L[w] + R[w] >> 1; build_tree(L(w),l,mid); build_tree(R(w),mid + 1,r); update(w);}int f[MAXN],g[MAXN];void add(int w,int loc,int x,int ch){ if(L[w] == R[w]) { if(ch) { maxf[w] = max(maxf[w],x); } else { maxg[w] = max(maxg[w],x); } return; } int mid = L[w] + R[w] >> 1; if(loc <= mid)add(L(w),loc,x,ch); else add(R(w),loc,x,ch); update(w);}int ask(int w,int l,int r,int v){ if(L[w] == l && R[w] == r) { return v ? maxg[w] : maxf[w]; } int mid = L[w] + R[w] >> 1; if(r <= mid)return ask(L(w),l,r,v); else if(l > mid)return ask(R(w),l,r,v); else return max(ask(L(w),l,mid,v),ask(R(w),mid + 1,r,v));}int ans;int tmp[MAXN];int main(){ scanf("%d",&n); for(int i = 1;i <= n;i ++) scanf("%d",&h[i]),tmp[i] = h[i]; sort(tmp + 1,tmp + n + 1); int tot = unique(tmp + 1,tmp + n + 1) - tmp - 1; for(int i = 1;i <= n;i ++) h[i] = lower_bound(tmp + 1,tmp + tot + 1,h[i]) - tmp,maxn = max(maxn,h[i]); build_tree(1,0,maxn + 1); f[1] = g[1] = 1; add(1,h[1],f[1],1); add(1,h[1],g[1],0); for(int i = 2;i <= n;i ++) { f[i] = ask(1,0,h[i] - 1,1) + 1; g[i] = ask(1,min(maxn,h[i] + 1),maxn,0) + 1; add(1,h[i],f[i],1); add(1,h[i],g[i],0); ans = max(ans,max(f[i],g[i])); } printf("%d",ans); return 0;}
转化类似于权值线段树?
阅读全文
0 0
- [codevs3289]花匠 线段树优化dp
- code vs 3289 花匠 (线段树优化dp)
- codevs 3289 花匠 (dp + 线段树)
- ZJU3349 线段树优化DP
- 数据--dp,线段树优化
- cf343D dp+线段树优化
- 【noip2013】花匠 DP||贪心
- [NOIP 2013]花匠 DP
- NOIP2013 花匠 dp/贪心
- 线段树和单调队列优化DP
- zoj 2900 DP(线段树优化)
- 【线段树优化dp】zoj3349 Special Subsequence
- 【DP+线段树优化】[CQBZOJ2933]数据
- hdu 4521(线段树优化dp)
- poj1769 Minimizing maximizer线段树优化dp
- bzoj1835(线段树优化dp)
- POJ 3170 线段树优化DP
- HDU-4722-线段树优化dp
- C、C++内存对齐
- 构造方法引用
- springmvc 用拦截器+token防止重复提交
- 时间、时间戳、带格式时间的转换
- 通过修改framework来达到过滤启动桌面的效果
- [codevs3289]花匠 线段树优化dp
- zmq错误Error: libzmq.so.3
- 两个有序的链表合并
- duty (图论题.二维前缀和)
- 《剑指offer》刷题笔记(代码完整性):打印1到最大的n位数
- 使用AndroidStudio开发工具实现多安装
- Android题目笔记(一)
- css3 animation 实现帧动画
- 实现类似微博视频滚动自动播放与暂停