题目:codevs 3289 花匠

链接:http://codevs.cn/problem/3289/

这道题有点像最长上升序列,但这里不是上升,是最长“波浪”子序列。用动态规划可以解决,方程类似最长上升子序列:

f[i]=max(f[j])  ( 1≤j≤i-1 && ( (f[j]%2=1 && A[j]<A[i] ) || (j%2=0 && A[j]>A[i]) )  )

p[i]=max(p[i])  (  1≤j≤i-1 && ( (p[j]%2=1 && A[j]>A[i] ) || (j%2=0 && A[j]<A[i]) )  )

结果:

ans=max(f[n],p[n])

...写出来,很恶心的方程,因为题目中是有两种情况,第一种是 第一个元素 < 第二个元素 开始的波浪序列,另一种是 第一个元素 > 第二个元素 开始的波浪序列。我这里的f[i]是第一种情况算出来的最长波浪序列,p[i]是第二种情况算出来的最长波浪序列,然后最后的答案是两者之间选一个最大的。这样用o(n²)的算法可以达成,但是注意,题目中的数据量是10,000 ,肯定时间要超,所以还是要用优化。

最长上升子序列中可以用线段树优化,那么这里怎么优化呢?

我的笨笨做法是开4个线段树:maxfj[],maxfo[],maxpj[],maxpo[]。

maxfj[]维护f[i]是奇数的最大值,maxfo[]维护f[i]是偶数的最大值。

maxpj[]维护p[i]是奇数的最大值,maxpo[]维护p[i]是偶数的最大值。

因为f[i]中,当f[i]是奇数的时候,区间是1到A[i]-1中的最大值,而当f[i]是偶数的时候,区间是A[i]+1到n的最大值(因为是严格单调,所以要+1或-1)。

当p[i]是奇数的时候,区间是A[i]+1到n的最大值,而当p[i]是偶数的时候,区间是1到A[i]-1中的最大值。

所以不能同时维护,要分开来,因此就是4个线段树。

当然,A[i]的值很大,要做离散化。

大致思路就是这样吧。

附代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<iostream>
  4. using namespace std;
  5. const int maxn=;
  6.  
  7. int n,maxfj[maxn*],maxfo[maxn*],f[maxn],p[maxn],maxpj[maxn*],maxpo[maxn*];
  8.  
  9. struct u
  10. {
  11. int v,r;
  12. bool operator <(const u &rhs) const
  13. {
  14. return v<rhs.v;
  15. }
  16. }A[maxn];
  17.  
  18. bool cmp(u a,u b)
  19. {
  20. return a.r<b.r;
  21. }
  22.  
  23. int w,v;
  24. void updatefj(int o,int L,int R)
  25. {
  26. if(L==R) maxfj[o]=max(maxfj[o],v);
  27. else
  28. {
  29. int M=(L+R)/;
  30. if(w<=M) updatefj(o*,L,M); else updatefj(o*+,M+,R);
  31. maxfj[o]=max(maxfj[o*],maxfj[o*+]);
  32. }
  33. }
  34.  
  35. int y1,y2,ans;
  36. void queryfj(int o,int L,int R)
  37. {
  38. if(y1<=L && R<=y2) ans=max(ans,maxfj[o]);
  39. else
  40. {
  41. int M=(L+R)/;
  42. if(y1<=M) queryfj(o*,L,M);
  43. if(y2>M) queryfj(o*+,M+,R);
  44. }
  45. }
  46. void updatefo(int o,int L,int R)
  47. {
  48. if(L==R) maxfo[o]=max(maxfo[o],v);
  49. else
  50. {
  51. int M=(L+R)/;
  52. if(w<=M) updatefo(o*,L,M); else updatefo(o*+,M+,R);
  53. maxfo[o]=max(maxfo[o*],maxfo[o*+]);
  54. }
  55. }
  56.  
  57. void queryfo(int o,int L,int R)
  58. {
  59. if(y1<=L && R<=y2) ans=max(ans,maxfo[o]);
  60. else
  61. {
  62. int M=(L+R)/;
  63. if(y1<=M) queryfo(o*,L,M);
  64. if(y2>M) queryfo(o*+,M+,R);
  65. }
  66. }
  67. void updatepj(int o,int L,int R)
  68. {
  69. if(L==R) maxpj[o]=max(maxpj[o],v);
  70. else
  71. {
  72. int M=(L+R)/;
  73. if(w<=M) updatepj(o*,L,M); else updatepj(o*+,M+,R);
  74. maxpj[o]=max(maxpj[o*],maxpj[o*+]);
  75. }
  76. }
  77.  
  78. void querypj(int o,int L,int R)
  79. {
  80. if(y1<=L && R<=y2) ans=max(ans,maxpj[o]);
  81. else
  82. {
  83. int M=(L+R)/;
  84. if(y1<=M) querypj(o*,L,M);
  85. if(y2>M) querypj(o*+,M+,R);
  86. }
  87. }
  88.  
  89. void updatepo(int o,int L,int R)
  90. {
  91. if(L==R) maxpo[o]=max(maxpo[o],v);
  92. else
  93. {
  94. int M=(L+R)/;
  95. if(w<=M) updatepo(o*,L,M); else updatepo(o*+,M+,R);
  96. maxpo[o]=max(maxpo[o*],maxpo[o*+]);
  97. }
  98. }
  99.  
  100. void querypo(int o,int L,int R)
  101. {
  102. if(y1<=L && R<=y2) ans=max(ans,maxpo[o]);
  103. else
  104. {
  105. int M=(L+R)/;
  106. if(y1<=M) querypo(o*,L,M);
  107. if(y2>M) querypo(o*+,M+,R);
  108. }
  109. }
  110.  
  111. int main()
  112. {
  113. cin>>n;
  114. for(int i=;i<=n;i++) cin>>A[i].v,A[i].r=i;
  115. //离散化
  116. sort(A+,A+n+);
  117. for(int i=,nw=;i<=n;i++)
  118. {
  119. f[i]=,p[i]=;//顺便做的f[],p[]初始化
  120. if(A[i+].v!=A[i].v) nw++,A[i].v=nw-;
  121. else A[i].v=nw;
  122. }
  123. sort(A+,A+n+,cmp);
  124.  
  125. w=A[].v,v=f[];
  126. updatefj(,,n);
  127. updatepj(,,n);
  128.  
  129. for(int i=;i<=n;i++)
  130. {
  131. y1=,y2=A[i].v-,ans=;
  132. if(y2>=y1) queryfj(,,n);//注意,因为有A[i]-1,所以要判断区间的存在
  133. y1=A[i].v+,y2=n;
  134. if(y2>=y1) queryfo(,,n);
  135. f[i]=ans+;
  136. v=f[i],w=A[i].v;
  137. if(f[i]%==) updatefj(,,n);
  138. else updatefo(,,n);
  139.  
  140. y1=,y2=A[i].v-,ans=;
  141. if(y2>=y1) querypo(,,n);
  142. y1=A[i].v+,y2=n;
  143. if(y2>=y1) querypj(,,n);
  144. p[i]=ans+;
  145. v=p[i],w=A[i].v;
  146. if(p[i]%==) updatepj(,,n);
  147. else updatepo(,,n);
  148. }
  149.  
  150. cout<<max(f[n],p[n]);
  151. return ;
  152. }

codevs 3289 花匠的更多相关文章

  1. Codevs 3289 花匠 2013年NOIP全国联赛提高组

    3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 花匠栋栋种了一排花,每株花都 ...

  2. 【CodeVS 3289】【NOIP 2013】花匠

    http://codevs.cn/problem/3289/ dp转移,树状数组维护前缀max和后缀max进行优化,$O(nlogn)$. #include<cstdio> #includ ...

  3. 花匠(codevs 3289)

    题目描述 Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花 ...

  4. noip2013 Day2 T2 花匠 解题报告

    题目: 3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大, ...

  5. 2013 Noip提高组 Day2

    3288积木大赛 正文 题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前 ...

  6. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  7. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

  8. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  9. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

随机推荐

  1. Hawk 4.7 单步调试

    单步调试的意义 已经编写的工作流,可能会因为某些外界环境的变化而出错,此时需要排除错误,我们可以使用单步调试. 单步调试的本质,相当于只使用前n个模块,这样就能看到每个步骤下,流的改变. 例子 还是上 ...

  2. RabbitMq应用一的补充(RabbitMQ的应用场景)

    直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...

  3. Collection集合

    一些关于集合内部算法可以查阅这篇文章<容器类总结>. (Abstract+) Collection 子类:List,Queue,Set 增: add(E):boolean addAll(C ...

  4. 【工具使用】mac电脑使用技巧

    本文地址 分享提纲: 1.  mac命令行和finder的交互 2. 一些mac的插件 3. 一些开发的配置 1.mac命令行和findder交互           1)命令行中打开当前文件夹: o ...

  5. DDD领域驱动设计 - 设计文档模板

    设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...

  6. “老坛泡新菜”:SOD MVVM框架,让WinForms焕发新春

    火热的MVVM框架 最近几年最热门的技术之一就是前端技术了,各种前端框架,前端标准和前端设计风格层出不穷,而在众多前端框架中具有MVC,MVVM功能的框架成为耀眼新星,比如GitHub关注度很高的Vu ...

  7. 说说BPM数据表和日志表中几个状态字段的详细解释

    有个客户说需要根据这些字段的值作为判断条件做一些定制化需求,所以需要知道这些字段的名词解释,以及里面存储的值具体代表什么意思 我只好为你们整理奉上这些了! Open Work Sheet  0 Sav ...

  8. H3 BPM产品安装手册(.Net版本)

    1         安装说明 1.1    服务器安装必备软件 在使用该工作流软件之前,有以下一些软件是必须安装: l  IIS7.0以上版本(必须): l  .Net Framework 4.5(必 ...

  9. SpringMVC视图解析器

    SpringMVC视图解析器 前言 在前一篇博客中讲了SpringMVC的Controller控制器,在这篇博客中将接着介绍一下SpringMVC视 图解析器.当我们对SpringMVC控制的资源发起 ...

  10. postgresql无法安装pldbgapi的问题

    要对函数进行调试需要安装插件pldbgapi,当初在windows上面的postgresql实例中执行了一下语句就安装上了: create extension pldbgapi; 但是在linux中执 ...