题目大意

给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列。

其中,n满足小于500000,序列中的正整数小于10^9

题解(引自mzx神犇的题解)

本次test跪0了,尴尬

解法1(40分)

考虑dp

设到第i个数为止,序列中数全部<=j的最小代价为f[i][j]

可以推出f[i][j]=min{f[i-1][j]+|ai-j|,f[i][j-1]}

解法2(60分)

是对于第一个dp思路的优化

既然数字是固定的,可以离散化,降低空间时间复杂度

解法3(100分)

斜率优化dp,用线段树维护斜率

解法4(100分,引自zyz大神的解法)

玄学的单调栈问题

由于区间中的数是单调不减的,所以最后得出的序列一定是一段一段的各个数值相等的序列区间

而要最小化代价,可以取这些区间中的中位数作为标准来修改每个区间,并用单调栈求解最优的区间划分

还需要用动态开点线段树维护区间中位数

orz

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. const int MAXN = 5e5 + ;
  5. const int INF = 1e9 + ;
  6.  
  7. inline int abs(int x){
  8. return x < ? -x : x;
  9. }
  10.  
  11. int Rin(){
  12. int x = , c = getchar(), f = ;
  13. for(; c < || c > ; c = getchar())
  14. if(!(c ^ ))
  15. f = -;
  16. for(; c > && c < ; c = getchar())
  17. x = (x << ) + (x << ) + c - ;
  18. return x * f;
  19. }
  20.  
  21. namespace Arcueid{
  22. struct Node{
  23. Node *l, *r;
  24. int s;
  25. Node(){}
  26. Node(Node *_l, Node *_r, int _s) : l(_l), r(_r), s(_s) {}
  27. }*_nil = new Node(), *nil = (*_nil = Node(_nil, _nil, ), _nil), pool[MAXN * ], *top = pool;
  28. Node *reborn(){
  29. *top = Node(nil, nil, );
  30. return top++;
  31. }
  32. void death(Node *&pr, Node *pl, int l, int r, int v){
  33. pr = reborn(); *pr = *pl; pr->s++;
  34. if(l + < r){
  35. int mid = (l + r) >> ;
  36. v < mid ? death(pr->l, pl->l, l, mid, v) : death(pr->r, pl->r, mid, r, v);
  37. }
  38. }
  39. int secret(Node *pr, Node *pl, int l, int r, int k){
  40. if(l + == r)return l;
  41. int c = pr->l->s - pl->l->s, mid = (l + r) >> ;
  42. return c < k ? secret(pr->r, pl->r, mid, r, k - c) : secret(pr->l, pl->l, l, mid, k);
  43. }
  44. int feel(Node *pr, Node *pl){
  45. int c = pr->s - pl->s;
  46. return secret(pr, pl, , INF, (c + ) >> );
  47. }
  48. }
  49.  
  50. Arcueid::Node *rt[MAXN] = {Arcueid::nil};
  51.  
  52. namespace moon{
  53. void cause(){
  54. int n, a[MAXN], stay = , night[MAXN], shiki[MAXN];
  55.  
  56. // freopen("chen.in", "r", stdin);
  57. // freopen("chen.out", "w", stdout);
  58.  
  59. n = Rin();
  60. for(int i = ; i <= n; i++){
  61. a[i] = Rin();
  62. Arcueid::death(rt[i], rt[i-], , INF, a[i]);
  63. for(; stay > && Arcueid::feel(rt[i], rt[night[stay - ]]) < shiki[stay - ]; stay--);
  64. shiki[stay] = Arcueid::feel(rt[i], rt[night[stay-]]);
  65. night[stay++] = i;
  66. }
  67. long long ans = ;
  68. for(int i = ; i < stay; i++)
  69. for(int j = night[i - ] + ; j <= night[i]; j++)
  70. ans += abs(a[j] - shiki[i]);
  71.  
  72. printf("%lld\n", ans);
  73. // fclose(stdin);
  74. // fclose(stdout);
  75. }
  76. }
  77.  
  78. int main(){
  79. moon::cause();
  80. return ;
  81. }

解法5(100分)

其实这个解法更玄

但最简洁的往往是最好的

  1. #include <queue>
  2. #include <vector>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <iostream>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9.  
  10. inline int read(){
  11. int x = , c = getchar(), f = ;
  12. for(; c < || c > ; c=getchar())
  13. if(!(c ^ ))
  14. f = -;
  15. for(; c > && c < ; c=getchar())
  16. x = (x << ) + (x << ) + c - ;
  17. return x * f;
  18. }
  19.  
  20. long long ans = ;
  21. priority_queue<int> q;
  22.  
  23. int main(){
  24. int n = read();
  25. for(int i = ; i <= n; i++){
  26. int x = read();
  27. q.push(x);
  28. ans += q.top() - x;
  29. if(x ^ q.top())
  30. q.pop();
  31. }
  32. printf("%lld\n", ans);
  33. return ;
  34. }

[2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)的更多相关文章

  1. BZOJ5059 前鬼后鬼的守护 【堆扩展】*

    BZOJ5059 前鬼后鬼的守护 Description 八云紫的式神八云蓝有一张符卡名为[式神-前鬼后鬼的守护],这张符卡的弹幕为BOSS从两侧向自机发射大玉,大玉后面跟着一些小玉,形成一个&quo ...

  2. BZOJ 5059: 前鬼后鬼的守护 可并堆 左偏树 数学

    https://www.lydsy.com/JudgeOnline/problem.php?id=5059 题意:将原序列{ai}改为一个递增序列{ai1}并且使得abs(ai-ai1)的和最小. 如 ...

  3. BZOJ 5059 前鬼后鬼的守护

    题解: 解法一:用函数斜率什么的,不会,留坑 解法二: 某一个序列都变成一个值那么中位数最优 加入一个元素,与前面那一段区间的中位数比较 x>=mid什么事也不做 x<mid合并两端区间 ...

  4. 探究C语言中的前++和后++

    小波带您探究c语言中的前++与后++: 欢迎吐槽,欢迎加QQ463431476. 欢迎关注!  现在来探究: 咱们先看第一个 i被赋值0,i++(后++)并没有输出1.   现在i被赋值0,++i,也 ...

  5. HMM 自学教程(七)前向后向算法

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  6. STL——前闭后开区间表示法和function call 操作符

    前开后闭开区间表示法[) 任何一个STL算法,都需要获得由一对迭代器(泛型指针)所标示的区间,用以表示操作范围,这一对迭代器所标示的是个所谓的前闭后开区间,以[first,last)表示,也就是说,整 ...

  7. HMM 前向后向算法(转)

    最近研究NLP颇感兴趣,但由于比较懒,所以只好找来网上别人的比较好的博客,备份一下,也方便自己以后方便查找(其实,一般是不会再回过头来看的,嘿嘿 -_-!!) 代码自己重新写了一遍,所以就不把原文代码 ...

  8. 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...

  9. jquery取前、后、父、子元素

    前.prev(); 后.next(); 父.parent(); 子.children(); 注意:前的前是.prev().prev(),例如前元素无i,但前的前的i元素有i,不能写成.prev('i' ...

随机推荐

  1. cursor.MySQLCursorDict Class

    5.9.6.4 cursor.MySQLCursorDict Class The MySQLCursorDict class inherits from MySQLCursor. This class ...

  2. Hibernate 小阶段总结

    (一)Hibernate入门 通俗的话来说:Hibernate是用于面向对象操控数据库,对JDBC进行轻量级封装.(在java世界中传统的来说是JDBC访问数据库.) 1)Hibernate定性:对象 ...

  3. 轻量的、可自定义 CSS 的 Lightbox 相册插件

    jQuery LightGallery是一个轻量级的,可定制的,模块化的,响应式的 jQuery 相册插件.它采用 CSS 来实现图像和视频的大小调整.因此,这将是非常灵活的,并且比使用 JavaSc ...

  4. 轻松掌握:JavaScript单例模式

    单例模式 定义:保证一个对象(类)仅有一个实例,并提供一个访问它的全局访问点: 实现原理:利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例; 主要用于:全局缓存.登录浮窗等只需要 ...

  5. Android开发的小技巧,在Android Studio中使用Designtime Layout Attributes

    在编写xml文件时,为了预览效果,经常会使用默认填上一些内容,比如TextView时,随便写上一个text <TextView ... android:text="Name:" ...

  6. GCD深入学习(1)dispatch_semaphore

    dispatch_semaphore信号量是一种基于计数器的一种多线程同步机制 在多个线程访问共有资源的时候,会因为多线程的特性引发数据出错. - (void)addData { dispatch_q ...

  7. 多行图片hover加边框兼容IE7+

    问题: 遇到多行多列排列的图片时,hover上去加边框会把下面的图片挤到别处 ============================================================ ...

  8. centos6.5和centos7如何搭建php环境

    作者:白狼 出处:http://www.manks.top/linux_php.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责 ...

  9. FastReport自定义数据源及ListView控件的使用

    ##1.想批量生成一堆物资信息卡,效果如下图所示,fastreport可以一下全部生成,并且发现不用单独写东西, ##2.发现FastReport官方给出的Demo.exe很友好,基本可以满足要求,想 ...

  10. linux 安装tomcat中间件

    1.首先确认是否已安装jdk.配置好所需要的环境变量,如果未安装好,则需要安装jdk和配置好正确的环境变量. 检查是否安装jdk及环境变量配置:#java -version. 2.如上述安装并配置正确 ...