WEASELSC code

给定一个高度图 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的更多相关文章

  1. Codechef SEPT17

    Codechef SEPT17 比赛链接:https://www.codechef.com/SEPT17 CHEFSUM code给定数组 a[1..n] ,求最小的下标 i ,使得 prefixsu ...

  2. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  3. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  4. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  5. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

  6. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  7. CodeChef CBAL

    题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...

  8. CodeChef FNCS

    题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...

  9. codechef Prime Distance On Tree(树分治+FFT)

    题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...

随机推荐

  1. BUPT复试专题—旋转图像(2014)

    题目描述 将一幅只含有01像素点的图片进行顺时针旋转,旋转的角度仅包含0°,90°,180°,270° 输入 第一行一个整数T(<50)表示输入的组数 每组测试数据第一行是两个整数N和M(< ...

  2. BUPT 2012复试机考 1T

    题目描述 大家都知道,数据在计算机里中存储是以二进制的形式存储的. 有一天,小明学了C语言之后,他想知道一个类型为unsigned int 类型的数字,存储在计算机中的二进制串是什么样子的. 你能帮帮 ...

  3. [Tools] Convert SVG to a PDF in Node with PDFKit and SVG.js

    Given a epxress application and an svg template, we want to draw some text, date onto it and convert ...

  4. push代码到github时,每次都要输入用户名和密码的问题

    问题原由 我在Github上 建立了一个小项目TauStreamingServer,可是在每次push代码 的时候,都要求输入用户名和密码,很是麻烦. 如何才能避免每次都输入用户名和密码呢? 解决办法 ...

  5. 如何干掉那些.ipch 与 .sdf文件

    参考资料: http://blog.163.com/yangjun1988422@126/blog/static/47412917201074446054/     vs2010中臃肿的ipch和sd ...

  6. C#语言基础语句

    case,switch,break的使用 Console.WriteLine("1.汉堡"); Console.WriteLine("2.薯条"); Conso ...

  7. 自己定义msi安装包的运行过程

    有时候我们须要在程序中运行还有一个程序的安装.这就须要我们去自己定义msi安装包的运行过程. 比方我要做一个安装管理程序,能够依据用户的选择安装不同的子产品.当用户选择了三个产品时,假设分别显示这三个 ...

  8. Android - 监听Activity点击无效

    监听Activity点击无效 本文地址: http://blog.csdn.net/caroline_wendy Activity须要先在Manifest注冊,才干在app中使用; Manifest: ...

  9. Iterator && Iterable Collection && Map

    Java集合类库将集合的接口与实现分离.同样的接口,可以有不同的实现. Java集合类的基本接口是Collection接口.而Collection接口必须实现Iterable接口. 以下图表示集合框架 ...

  10. fstab文件解析

    1 这个文件的用途 这个文件是启动时自动挂载指定的磁盘或者分区到系统目录下用的,提供给mount命令用. 2 文件解析 每一行是一次mount操作. 磁盘或者分区    挂载的目录     挂载的磁盘 ...