[bzoj4368][IOI2015]boxes纪念品盒_动态规划_单调队列_贪心
bzoj4368 IOI2015 boxes纪念品盒
题目链接:https://lydsy.com/JudgeOnline/problem.php?id=4368
数据范围:略。
题解:
如果在一个最优方案中,一个点$i$是这个人拿东西从左侧走过来的,我们就说这个点是蓝的。
如果是右侧的,就说这个点是红。
我们发现,并不存在三个可以不连续的点,满足红蓝红。
即,一定存在一个点$i$,满足$1\sim i$的点是蓝的,$i + 1\sim n$是红的。
接着我们维护一个$dp$状态:$f_i$,表示从$0$开始,把$1\sim i$都从左侧删掉并且回到原点的最小代价;$g_i$表示右侧的最小代价。
考虑$f$怎么转移?
显然,$f_i = min\{ f_j \} (i-j\le k)+a_i+min(a_i, L - a_i)$。
这个可以用线段树啊树状数组什么的优化。但是因为$n$是$10^7$,所以我们用单调队列即可。
代码:
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define N 10000010
using namespace std;
typedef long long ll;
char *p1, *p2, buf[100000];
#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
int rd() {
int x = 0;
char c = nc();
while (c < 48) {
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x;
}
int q[N], a[N];
ll dis[N], f[N], g[N];
int main() {
// setIO("box");
int n = rd(), k = rd(), L = rd();
for (int i = 1; i <= n; i ++ ) {
a[i] = rd();
dis[i] = min(a[i], L - a[i]);
}
int head = 1, tail = 0;
q[ ++ tail] = 0;
for (int i = 1; i <= n; i ++ ) {
f[i] = f[q[head]] + a[i] + dis[i];
while (head <= tail && f[i] < f[q[tail]])
tail -- ;
while (head <= tail && i - q[head] >= k) {
head ++ ;
}
q[ ++ tail] = i;
}
head = 1, tail = 0;
q[ ++ tail] = n + 1;
for (int i = n; i; i -- ) {
g[i] = g[q[head]] + L - a[i] + dis[i];
while (head <= tail && g[i] < g[q[tail]]) {
tail -- ;
}
while (head <= tail && q[head] - i >= k) {
head ++ ;
}
q[ ++ tail] = i;
}
// for (int i = 0; i <= n + 1; i ++ ) {
// printf("%d : %lld %lld\n", i, f[i], g[i]);
// }
ll ans = 0x3f3f3f3f3f3f3f3fll;
for (int i = 0; i <= n; i ++ ) {
ans = min(ans, f[i] + g[i + 1]);
}
cout << ans << endl ;
}
[bzoj4368][IOI2015]boxes纪念品盒_动态规划_单调队列_贪心的更多相关文章
- 题解 [BZOJ4368][IOI2015]boxes纪念品盒
题面 解析 可以发现,发纪念品有三种方式: 从左边走再原路返回. 从右边走再原路返回. 走一圈. 注意到,第三种走法最多只会走一次, 因为如果走了多次,那发放的物品数量就会>=\(2k\), 那 ...
- 4368: [IOI2015]boxes纪念品盒
4368: [IOI2015]boxes纪念品盒 链接 分析 链接 代码 #include<bits/stdc++.h> using namespace std; typedef long ...
- IOI2015 boxes纪念品盒
BZOJ 4368: [IOI2015]boxes纪念品盒 BZOJ传送门 Description IOI2015开幕式正在进行最后一个环节.按计划在开幕式期间,每个代表队都将收到由主办方发放的一个装 ...
- [BZOJ] IOI2015 Boxes纪念品盒
问题描述 IOI2015 开幕式正在进行最后一个环节.按计划在开幕式期间,每个代表队都将收到由主办方发放的一个装有纪念品的盒子.然而所有志愿者都被精彩的开幕式所吸引,除 Aman外其他人完全忘记了发放 ...
- BZOJ 4368: [IOI2015]boxes纪念品盒
三种路径,左边出去左边回来,右边出去右边回来,绕一圈 绕一圈的路径最多出现一次 那么绕一圈的路径覆盖的点一定是左边半圈的右边和右边半圈的左边 枚举绕一圈的路径的起始点(一定要枚举,这一步不能贪心),更 ...
- BZOJ 4368: [IOI2015]boxes纪念品盒 贪心
题意:给定一个环,环上有一些点包裹,你要从 $0$ 号点出发,然后每次带上一个容量为 $k$ 的背包. 问:如果要把所有的包裹都带回 $0$ 好点最少要走多少距离. 每一次只有 $3$ 种走法:走整圆 ...
- 【BZOJ2442】修建草坪(动态规划,单调队列)
[BZOJ2442]修建草坪(动态规划,单调队列) 题面 权限题..洛谷 题解 设\(f[i]\)表示前\(i\)个里面选出来的最大值 转移应该比较显然 枚举一个断点的位置,转移一下就好 \(f[i] ...
- 【BZOJ1855】股票交易(动态规划,单调队列)
[BZOJ1855]股票交易(动态规划,单调队列) 题面 BZOJ 题解 很显然,状态之和天数以及当天剩余的股票数有关 设\(f[i][j]\)表示第\(i\)天进行了交易,剩余股票数为\(j\)的最 ...
- 【CF1133E】K Balanced Teams(动态规划,单调队列)
[CF1133E]K Balanced Teams(动态规划,单调队列) 题面 CF 让你把一堆数选一些出来分成不超过\(K\)组,每一组里面的最大值和最小值之差不超过\(5\),求最多有多少个人元素 ...
随机推荐
- Gym - 102346G Getting Confidence 最小费用最大流
Gym - 102346GGetting Confidence 题意:n*n的格子,每个格子上有一个数,要求每行每列都只能拿一个数,使得乘积最大,然后输出每列选择的是第几行的数. 如果是加法的话,那么 ...
- ansible handlers
示例:安装nginx --- - hosts: hadoop #指定主机组 remote_user: root #远程执行命令的用户 gather_facts: no #是否获取远程主机的信息 tas ...
- ShardingSphere Hint模式 SpringBoot + Mybatis
ShardingSphere Hint模式不需要对sql进行解析,就可以进行数据库或者表的路由.下面贴一下代码,关于SpringBoot + Mybatis + ShardingSphere怎样结合. ...
- win10 合并磁盘 disk Acronis Disk Director
硬盘调整C盘大小的工具.zip 无损分区软件(Acronis Disk Director)下载 11.0 破解版 ADD11H_trial_en-US(11.0.0.2343).exe 注册码: E ...
- Oracle scope中 spfile、memory、both 的区别
Oracle里面有个叫做spfile的东西,就是动态参数文件,里面设置了Oracle 的各种参数. 所谓的动态,就是说你可以在不关闭数据库的情况下,更改数据库参数,记录在spfile里面. 更改参数的 ...
- SOCKET_CONNECT_TIMEOUT is the timeout for the connection to be established and SOCKET_TIMEOUT
https://github.com/niwinz/django-redis/blob/master/doc/content.adoc#32-socket-timeout 3.2. Socket ti ...
- redis不支持多个数据库实例但是支持多个字典
Redis多个数据库 注意:Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念. Redis是一个字典结构的存储服务器,而实际上一个Redi ...
- opencv常见示例
1.批量转换灰度图并保存 #include <iostream> #include <opencv2/opencv.hpp> #include <string> u ...
- VSCode 设置 Tab 空格
Windows 点击左下角的 Setting 按钮 输入 tabSize 进行查找
- 优雅编写Python3 的62个小贴士
iterable技巧 ▍1.创建一个数字序列(从0到10,间隔为2) >>> range(0,10,2)[0, 2, 4, 6, 8] ▍2.对一串数字求和(从0到10,间隔为2 ...