Codechef WEASELSC
给定一个高度图 a[1..n] ,要求你减少图中一些地方的高度,使得得到的图是一个不超过 K 级的楼梯,要求楼梯的面积最大(即得到的图中所有位置的高度之和最大)。
这题题面特别不清晰,我们现在要形式化这个问题。
给定一个数组 a[1..n] ,要求找到一个数组 b[1..n],使得
1. 对任意$1 \le i \le n$,有$0 \le b[i] \le a[i]$。
2. 存在 $1 \le L \le R \le n$,使得
2.0. 对任意 $1 \le i < L$ 或 $R < i \le n$,都有$b[i] = 0$。
2.1. 子数组 b[L..R] 是一个楼梯,并且楼梯级数不超过 K 。
3. 最大化 $sum(b) = \sum_{i=1}^n b[i]$。
一个数组 a[1..n] 是一个楼梯,如果 a[1..n] 单调,即 a[1..n] 单调(非严格)递增 或 单调(非严格)递减。
一个楼梯 a[1..n] 的级数为
$$ step(a[1..n]) = \sum_{i=2}^n [a[i] \neq a[i-1]]. $$
解:
这题是贪心与动态规划结合的题目,所以在解题之前要观察题目的一些性质。
观察0:若我们解决了单调递增楼梯的问题,则我们把整个数组 a[1..n] 翻转过来,即可解决单调递减楼梯的问题。
因此我们只需要考虑单调递增楼梯的求解。
观察1:若b[1..n]是满足条件并且最大化 $sum(b)$ 的数组,则存在 $1 \le i \le n$,使得 $b[i] = a[i]$ 且 b[i] 是最高的那一级楼梯。
观察2:若我们选定了某个 $1 \le i \le n$,使得 $b[i] = a[i]$ 作为整个楼梯最高级的高度,则贪心地往两边延伸,直到碰到比 a[i] 小的位置为止。
于是,我们可枚举最高级楼梯的高度所在的位置 i,从左右延伸得到一个高度为 a[i] 的平台,范围是 [L, R] 。
由于当前枚举的是最高级的楼梯,因此在 R 的右边不存在任何楼梯,我们只需要考虑 L 的左边的情况。
此时,必定有 a[L-1] < a[L] (我们额外定义 a[0] = -1 以处理边界情况)。
于是接下来的问题就是,如何利用 1..L-1 来建造 K-1 级楼梯,并且要求楼梯最右侧位于 L-1,以及使得楼梯的高度之和最大,我们令 f[L][K] 表示这个最大值。
对特定的 a[i],我们把上述 L, R 分别记作 L[i], R[i]。
有动态规划方程
$$ f[i][k] = \max_{0 \le j < i} \{ f[j][k-1] + (i-j)a[j] : a[j] < a[p], \forall j < p < i \}. $$
以及边界条件 $f[0][k] = f[i][0] = 0$。
这是一个可以斜率优化的式子,我们把式子整理一遍,可得
$$ f[i][k] = \max_{0 \le j < i} \{ f[j][k-1]-ja[j] + ia[j] : a[j] < a[p], \forall j < p < i \}. $$
若令$x[j] = a[j], y[j] = f[j][k-1]-ja[j]$,则式子更加直观
$$ f[i][k] = \max_{0 \le j < i} \{ i x[j] + y[j] : a[j] < a[p], \forall j < p < i \}. $$
我们现在考虑哪些 j 可以被纳入动态规划的候选名单中。
我们记
$$ S(i) = \{ j : 0 \le j < i, a[j] < a[p], \forall j < p < i \}. $$
观察3:如果L[i] = L[j],则S(i) = S(j)。
观察4:如果$j_1, j_2 \in S(i)$,则 $j_1 < j_2$ 当且仅当 $a[j_1] < a[j_2]$。
于是,我们在依次枚举 j = 1..n 的过程中,可以用单调队列维护集合 S,而拥有相同当前集合 S = S(i) 的 i 则满足 L[i] = j。
这时,集合 S 中用单调队列维护二维上凸壳 (x[j], y[j]) ,对于每个 i,可以利用二分法求得斜率为 i 的取最优解的二维点,并带入计算得到 f[i][k]。
时间复杂度 $O(Kn \log n)$ 。
Codechef WEASELSC的更多相关文章
- Codechef SEPT17
Codechef SEPT17 比赛链接:https://www.codechef.com/SEPT17 CHEFSUM code给定数组 a[1..n] ,求最小的下标 i ,使得 prefixsu ...
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- 【BZOJ4260】 Codechef REBXOR 可持久化Trie
看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...
- codechef 两题
前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...
- codechef January Challenge 2014 Sereja and Graph
题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...
- BZOJ3509: [CodeChef] COUNTARI
3509: [CodeChef] COUNTARI Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 339 Solved: 85[Submit][St ...
- CodeChef CBAL
题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...
- CodeChef FNCS
题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...
- codechef Prime Distance On Tree(树分治+FFT)
题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...
随机推荐
- UVa567_Risk(最短路)(小白书图论专题)
解题报告 option=com_onlinejudge&Itemid=8&category=7&page=show_problem&problem=508"& ...
- Jenkins系列之-—07 集成JIRA
一.Jenkins Jira插件安装&配置 1. 安装插件,主要安装如下插件: Jira Issue Updater 该插件用于更新JIRA ISSUES 的工作流状态或增加备注 JIRA p ...
- 《Java虚拟机原理图解》4.JVM机器指令集
0. 前言 Java虚拟机和真实的计算机一样,执行的都是二进制的机器码:而我们将.java 源码编译成.class 文件,class文件便是Java虚拟机可以认识的二进制机器码,Java可以识别cla ...
- Python - scrapy安装中libxml2问题
先到 http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 下载下面三个库的 whl,然后用pip install 来安装即可 pycurl,lxml,lib ...
- Java 线程池ThreadPoolExecutor简单应用
什么是线程池: 线程池就是控制线程的一个池子.用来控制线程数量. 为什么要使用线程池: 1.避免系统反复创建和销毁线程影响执行的时间(创建+销毁>>执行时间时) 2.控制线程数量.线程过多 ...
- ObjectARX学习笔记(三十二)----怎样设置AcDbMText对齐方式
//_T("\\pxql;") 居左 //_T("\\pxqr;") 居右 //_T("\\pxqc;") 居中 //_T("\\ ...
- ES6常用语法简介import export
ES6常用语法简介import export let与var用法区别 //var var a = []; for (var i = 0; i < 10; i++) { a[i] = functi ...
- C/C++用状态转移表联合函数指针数组实现状态机FSM
状态机在project中使用很的频繁,有例如以下常见的三种实现方法: 1. switch-case 实现.适合简单的状态机. 2. 二维状态表state-event实现.逻辑清晰.可是矩阵通常比較稀疏 ...
- NullpointerException真的一定要被预防?
毫无疑问,空指针NullpointerException是我们最常遇到异常,没有之一! 在刚进入编程职业时,我想,大部分进入的同学肯定会受到前辈们的叮咛:一定要防止空指针,这是个低级错误.你们不是?好 ...
- Axure Base 07 元件使用思路的补充
我们曾经对axure线框图基本元件进行过说明,现结合这我对这些元件的使用习惯,对部分元件的使用,再做一些补充. 1. 图片:可以编辑悬停.按下时候显示不同的图片,做图片的一些特殊效果. 2. 文本(l ...