CSP2019 Day2T2 划分
很显然有一个暴力 \(dp\),令 \(dp_{i, j}\) 表示最后一次划分在 \(i\) 上次划分在 \(j\) 的最小花费,令 \(S_i = \sum\limits_{j = 1} ^ i a_j\)。那么有转移:
\]
可以发现 \(dp_{j, k}\) 的值是和 \(i\) 无关的,只是 \(k\) 的取值范围和 \(i\) 有关,那么我们只需要知道 \(k\) 的取值范围再取这个范围内的最小值即可。将后面那个条件移项可得 \(S_k \ge 2 \times S_j - S_i\),因此 \(k\) 的取值范围应该在 \(2 \times S_j - S_i \sim j - 1\),而当 \(j\) 固定时,因为 \(S_i\) 随着 \(i\) 的增大单调递增,所以 \(k\) 能取到的下界不断减小,于是我们可以考虑在 \(i\) 的同时维护每个 \(j\) 的下界以及当前能取到的最小 \(dp_{j, k}\) 这样均摊复杂度就是 \(O(n ^ 2)\) 的了。
rep(i, 1, n) dp[i][0] = sum[i] * sum[i], p[i] = i - 1, mx[i] = inf;
rep(i, 2, n){
rep(j, 1, i - 1){
while(p[j] >= 0 && sum[p[j]] >= 2 * sum[j] - sum[i]) mx[j] = min(mx[j], dp[j][p[j]]), --p[j];
if(p[j] < j - 1) ++p[j];
if(mx[j] != inf) dp[i][j] = mx[j] + (sum[i] - sum[j]) * (sum[i] - sum[j]);
}
}
rep(i, 0, n - 1) ans = min(ans, dp[n][i]);
printf("%lld", ans);
return 0;
如果这个 \(dp\) 不能压缩状态是显然无法优化的,但为了保证题目中的条件,我们根本无法压缩状态,下面一个常见的手段就是可以打个决策转移的表。可以发现我们每次转移 \(j \rightarrow i\) 都是选择了一个最大的能满足条件的 \(k\) 从 \(dp_{j, k} \rightarrow dp_{i, j}\),并且可以发现当 \(j\) 越大时 \(dp_{i, j}\) 越大。这样换句话来说就是每次我们让最后一段尽可能选择小的是更优的,实际上因为我们有 \((a + b) ^ 2 > a ^ 2 + b ^ 2\) 因此我们要尽可能多分段,如果我们每次选择最小的一段,不仅能够分更多的段,并且还能让后面尽可能分的段更多,并且能让当前的贡献更小,所以这样做一定是更优的。针对这个贪心,我们可以令 \(dp_i\) 表示当前划分到以 \(i\) 结尾的段的最小花费,令 \(p_i\) 表示 \(i\) 是由哪里转移来的,那么每次转移就要找到一个最大 \(j\) 满足 \(S_i - S_j \ge S_j - S_{p_j}\) 移项可得 \(S_i \ge 2 \times S_j - S_{p_j}\),我们大可以使用线段树二分出左边第一个比某个数大的位置,但实际上这里还有个 \(O(n)\) 做法。可以发现因为 \(S_i\) 是单调递增的,因此我们之前能够选择的 \(j\) 随着 \(i\) 的增大一定是还能继续选的。因此我们可以维护一个类似单调队列的东西,在队列中 \(2 \times S_j - S_{p_j}\) 单调递增,每次我新加入一个元素,从队尾一直开始弹出知道这个 \(2 \times S_{q_t} - S_{p_{q_t}} < 2 \times S_j - S_{p_j}\) 为止,那么这样我们获得的每个值的位置都将是当前最靠右的点,并且由于 \(S_i\) 在不断单调递增,我们只需要每次不断移动队尾找到队列中最后一个 \(\le S_i\) 的元素即可。
dp[1] = a[1] * a[1], h = 1, t = 2, q[1] = 0, q[2] = 1;
rep(i, 2, n){
while(h <= t && 2 * sum[q[h]] - sum[p[q[h]]] <= sum[i]) ++h;
--h, p[i] = q[h];
dp[i] = dp[p[i]] + (sum[i] - sum[p[i]]) * (sum[i] - sum[p[i]]);
while(h <= t && 2 * sum[i] - sum[p[i]] <= 2 * sum[q[t]] - sum[p[q[t]]]) --t;
q[++t] = i;
}
printf("%lld", dp[n]);
最后那 \(12\) 分需要使用高精度,根据我们的流程可以看出实际上我们不需要记录 \(dp\) 数组,只需要记录之前的 \(p\) 即可,最后我们只需要不断往下迭代加上每一段的值即可,我的高精太丑了(其实是写的 \(\_\_int128\))就不贴了。
CSP2019 Day2T2 划分的更多相关文章
- CSP2019 D2T2 划分 (单调队列DP)
题目 洛谷传送门 题解 就是这道题搞我退役考场上写了n^2 64分,结果爆成8-12分.直接GG. 考场上想到正解的写法被自己否决了 题解传送门(看到这道送我退役的题目⑧太想写题解) 六行O(n2)O ...
- 【CSP2019】题解合集
诈个尸 先挖坑 虽然连去都没去但还是想做做 今年貌似比去年还毒瘤啊... yrx.hjw都进了省队线tql orz (myh:没AK真丢脸 Day1T1 格雷码 Day1T2 括号树 Day1T3 树 ...
- CSP-S 2019 Solution
Day1-T1 格雷码(code) 格雷码是一种特殊的 \(n\) 位二进制串排列法,要求相邻的两个二进制串恰好有一位不同,环状相邻. 生成方法: \(1\) 位格雷码由两个 \(1\) 位的二进制串 ...
- CSP2019 S2滚粗记
最好分数:100+20+10+64+64+55 最坏分数:100+20+10+64+36+55 咕咕数据分数:100+25+10+64+60+55 CCF官方: 100+35+10+64+36+55= ...
- CSP2019题解
CSP2019题解 格雷码 按照生成的规则模拟一下即可. 代码 括号树 看到括号匹配首先想到用栈,然后又在树上就可以想到可追溯化栈. 令\(a_i=1\)表示\(i\)号节点上的括号为(,否则为), ...
- CSP2019 题解
CSP2019 题解 D1T1 格雷码(code) 题目传送门 https://loj.ac/problem/3208 题解 按照题意模拟就可以了. 对于第 \(i\) 位,如果 \(k \geq 2 ...
- [LeetCode] Partition List 划分链表
Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...
- SWMM模型子汇水区划分的几种方法
子汇水区的划分是SWMM模型建模的主要步骤之一,划分的好坏对结果精度有比较大的影响.概括来讲,子汇水区的划分有以下几种思路: (1)根据管网走向.建筑物和街道分布,直接人工划分子汇水区.这个方法适用于 ...
- 等价类划分方法的应用(jsp)
[问题描述] 在三个文本框中输入字符串,要求均为1到6个英文字符或数字,按submit提交. [划分等价类] 条件1: 字符合法; 条件2: 输入1长度合法; 条件3: 输入2长度合法: 条件4: 输 ...
随机推荐
- 第二十七个知识点:什么是对称密码加密的AEAD安全定义?
第二十七个知识点:什么是对称密码加密的AEAD安全定义? AEAD 在之前的博客里,Luke描述了一种被广泛使用的操作模式(ECB,CBC和CTR)对块密码.我们也可能会想我们加密方案的完整性,完整性 ...
- Regularizing Deep Networks with Semantic Data Augmentation
目录 概 主要内容 代码 Wang Y., Huang G., Song S., Pan X., Xia Y. and Wu C. Regularizing Deep Networks with Se ...
- Java 设置系统参数和运行参数
系统参数 系统级全局变量,该参数在程序中任何位置都可以访问到.优先级最高,覆盖程序中同名配置. 系统参数的标准格式为:-Dargname=argvalue,多个参数之间用空格隔开,如果参数值中间有空格 ...
- Nginx_全局命令设置
刚安装好的Nginx, 命令需要去sbin目录执行,比较麻烦,设置下全局命令,就无需进入nginx的sbin目录执行nginx命令了 1.创建文件 vim /etc/init.d/nginx 把下面代 ...
- win10快捷方式小箭头怎么去掉
为了演示,先来看看桌面图标是有小箭头的. 1.打开注册表 按下快捷键"win+R",然后输入"regedit",并点击确认按钮. 2.搜索HKEY_CLASSE ...
- Apache Ant: If 和 Unless
目录 If And Unless If And Unless 从 Ant 1.9.1 起,可以在所有的任务和嵌套的元素上以特别的命名空间添加 if 和 unless 属性. In order to u ...
- SCryptPasswordEncoder 单向加密 --- 心得
1.前言 * BCryptPasswordEncoder相关知识:* 用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的s ...
- Swagger的应用
一.介绍 一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 框架. 二.依赖 <dependency> <groupId>io.springf ...
- 离线环境安装使用 Ansible
之前写了一篇介绍 Ansible 的文章 ,今天回顾看来写的有些匆忙,一些具体的操作步骤都没有讲明白,不利于读者复现学习.最近又申请了一个几百台机器的环境,正好借此机会把如何在离线环境中使用 Ansi ...
- JVM调优2-远程监控
监控远程JVM VisualJVM不仅是可以监控本地jvm进程,还可以监控远程的jvm进程,需要借助于JMX技术实现. 什么是JMX JMX(Java Management Extensions,即J ...