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),他们之间的长度为素数的概率为多大? 树分治 ...
随机推荐
- axis2调用WSDL接口
public static JSONObject sendWsdl(String url,String xmlStr){ JSONObject res=new JSONObject(); try { ...
- [WASM] Access WebAssembly Memory Directly from JavaScript
While JavaScript has a garbage-collected heap, WebAssembly has a linear memory space. Nevertheless u ...
- Solidworks如何显示装饰螺纹线
1 工具-选项 2 文档属性-上色的装饰螺纹线 3 这样我再插入装饰螺纹线的时候就有效果了
- 线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters
题意:有一个非常长的板子(10000000长),在上面贴n(n<=10000)张海报.问最后从外面能看到几张不同的海报. 由于板子有10000000长,直接建树肯定会爆,所以须要离散化处理,对于 ...
- leetcode题解||Container With Most Water问题
problem: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate ...
- CPU Stepping
http://baike.baidu.com/view/16839.htm?fr=ala0_1_1 步进 编辑 步进(Stepping)是CPU的一个重要参数,也叫分级鉴别产品数据转换规范,“步进 ...
- 当年用httpclient时踩过的那些坑
一.前言 httpclient是java开发中最常用的工具之一,通常大家会使用其中比较基础的api去调用远程.长期开发爬虫,会接触httpclient不常用的api,同时会遇到各式各样的坑,本文将总结 ...
- Cocos2d-js异步图片加载
这里说的是在需要的使用加载图片,比如游戏中的某个关卡的图片,不用在游戏一开始就加载(万一用户玩不到那关,岂不是很冤,流量费了那么多),否则 载入速度也慢.这种方式加载资源要用到cc.loader官方文 ...
- 在Qt Creator中为Qt工程添加资源
1.右键单击工程 -> Add New ... -> Qt -> Qt Resource File -> Choose... -> Name: -> Next -& ...
- Java,如何获取文件的MD5值
MessageDigest类封装得很不错,简单易用 不多说,直接上代码 import java.io.FileInputStream;import java.security.MessageDiges ...