题目大意

给定一个长度为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

#include <stdio.h>
#include <string.h> const int MAXN = 5e5 + ;
const int INF = 1e9 + ; inline int abs(int x){
return x < ? -x : x;
} int Rin(){
int x = , c = getchar(), f = ;
for(; c < || c > ; c = getchar())
if(!(c ^ ))
f = -;
for(; c > && c < ; c = getchar())
x = (x << ) + (x << ) + c - ;
return x * f;
} namespace Arcueid{
struct Node{
Node *l, *r;
int s;
Node(){}
Node(Node *_l, Node *_r, int _s) : l(_l), r(_r), s(_s) {}
}*_nil = new Node(), *nil = (*_nil = Node(_nil, _nil, ), _nil), pool[MAXN * ], *top = pool;
Node *reborn(){
*top = Node(nil, nil, );
return top++;
}
void death(Node *&pr, Node *pl, int l, int r, int v){
pr = reborn(); *pr = *pl; pr->s++;
if(l + < r){
int mid = (l + r) >> ;
v < mid ? death(pr->l, pl->l, l, mid, v) : death(pr->r, pl->r, mid, r, v);
}
}
int secret(Node *pr, Node *pl, int l, int r, int k){
if(l + == r)return l;
int c = pr->l->s - pl->l->s, mid = (l + r) >> ;
return c < k ? secret(pr->r, pl->r, mid, r, k - c) : secret(pr->l, pl->l, l, mid, k);
}
int feel(Node *pr, Node *pl){
int c = pr->s - pl->s;
return secret(pr, pl, , INF, (c + ) >> );
}
} Arcueid::Node *rt[MAXN] = {Arcueid::nil}; namespace moon{
void cause(){
int n, a[MAXN], stay = , night[MAXN], shiki[MAXN]; // freopen("chen.in", "r", stdin);
// freopen("chen.out", "w", stdout); n = Rin();
for(int i = ; i <= n; i++){
a[i] = Rin();
Arcueid::death(rt[i], rt[i-], , INF, a[i]);
for(; stay > && Arcueid::feel(rt[i], rt[night[stay - ]]) < shiki[stay - ]; stay--);
shiki[stay] = Arcueid::feel(rt[i], rt[night[stay-]]);
night[stay++] = i;
}
long long ans = ;
for(int i = ; i < stay; i++)
for(int j = night[i - ] + ; j <= night[i]; j++)
ans += abs(a[j] - shiki[i]); printf("%lld\n", ans);
// fclose(stdin);
// fclose(stdout);
}
} int main(){
moon::cause();
return ;
}

解法5(100分)

其实这个解法更玄

但最简洁的往往是最好的

#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; inline int read(){
int x = , c = getchar(), f = ;
for(; c < || c > ; c=getchar())
if(!(c ^ ))
f = -;
for(; c > && c < ; c=getchar())
x = (x << ) + (x << ) + c - ;
return x * f;
} long long ans = ;
priority_queue<int> q; int main(){
int n = read();
for(int i = ; i <= n; i++){
int x = read();
q.push(x);
ans += q.top() - x;
if(x ^ q.top())
q.pop();
}
printf("%lld\n", ans);
return ;
}

[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. [原创小工具]软件内存、CPU使用率监视,应用程序性能监测器 v3.0 绿色版

    应用程序性能监测器 V3.0 更新内容:    1.对一些代码进行了修改,软件本身的性能有所提升. 应用程序性能监测器 V2.0 更新内容:     1.鼠标移动到曲线区域,显示相关的曲线值      ...

  2. Linux(一)__入门介绍

    linux的特点 优点: 1.免费的/开源的系统 2.支持多线程/多用户的系统 3.安全性好 4.对内存和文件管理优越 5.提供了丰富的网络功能 6.良好的用户界面.图形化界面和字符型界面 linux ...

  3. (原) 1.3 zookeeper脚本使用

    本文为原创文章,转载请注明出处,谢谢 zookeeper自带脚本使用 1.进入zookeeper客户端 找到安装目录下的bin目录,执行以下脚本(中括号标示被必填) ./zkCli.sh  -time ...

  4. 移动页面div居中效果代码

    在线查看效果:http://hovertree.com/texiao/mobile/4.htm 可用手机浏览器查看 以下为HTML文件: <!DOCTYPE html> <html& ...

  5. 又到周末了,我们一起来研究【浏览器如何检测是否安装app】吧

    前言 扯淡 这个月比较倒霉,我送了女朋友一台笔记本电脑作为生日礼物,结果15天一过电脑就坏了,悲剧的我还把电脑盒子给扔了!淘宝不给换更不给退 于是被女朋友臭骂了一过星期后,今天本来在公司有任务的,但是 ...

  6. angular源码分析:angular中入境检察官$sce

    一.ng-bing-html指令问题 需求:我需要将一个变量$scope.x = '<a href="http://www.cnblogs.com/web2-developer/&qu ...

  7. AngularJS在IE8的支持

    AngularJS一般不会选择IE8支持, 因为很多特性在IE8下效果很差, 性能也不好, 但是由于项目的需要, 客户的机器有些是XP, 只能够装IE8, 所以为了解决这个, 我查阅了相关的资料,发现 ...

  8. Linux2.6内核进程调度系列--scheduler_tick()函数1.总体思想

    参考的是ULK第三版,Linux2.6.11.12内核版本. 调度程序依靠几个函数来完成调度工作,其中最重要的第一个函数是scheduler_tick函数,主要步骤如下: /** * 维持当前最新的t ...

  9. 学习linux之用mail命令发邮件

    背景 这两天工作比较闲,网上各种冲浪(这个词暴露我的网龄了).看到一位大神的文章更闲 <>.端详一番,原来是用R语言拼接字符串后用shell命令发出去.发现shell命令既然还能直接发邮件 ...

  10. Oracle数据库shutdown immediate被hang住的几个原因

    实验操作环境:         操作系统:Red Hat Enterprise Linux ES release 4 (Nahant Update 6)                         ...