[HG]走夜路 题解
前言
整个机房就我一个人在想动态规划。
想了半天发现一堆性质,结果由于DP中出现折线挂了。
题目描述
某NOIP普及组原题加强版。
\(Jim\) 非常怕黑,他有一个手电筒,设手电筒的电量上限为 \(T\) 。
\(Jim\) 回家的路上有 \((N + 1)\) 个充电站, \(0\) 是起点 \(N\) 是终点,
\(Jim\) 每走一个单位距离消耗一个单位的电量。
给出每个充电站到下一个充电站的距离 \(D\) ,以及冲单位电量的花费 \(P\) ,求整个旅途的最少花费。
P.S. 如果 \(Jim\) 无法保证全程 手电筒都亮着输出 \(-1\) 。
题解
有一个美妙的贪心。
对于当前 \(Jim\) 所在的点,
如果能走到 \(P\) 值比它小的充电站,就适量地充电并走到它,使走到第一个 \(P\) 值小于他的充电站时花费的钱最小;
如果走不到或找不到这样一个点就充满电,走到下一个充电站。
那么怎么找到第一个 \(P\) 值小于它的点呢,简单第使用二分加ST表即可。
时间复杂度为 \(\Theta(n\ logn)\)。
代码
#include <cstdio>
#define int long long
int st[500005][26];
int lg2[500005];
int d[500005], p[500005];
#define min(a,b) ((a<b)?a:b)
void init(int n){
lg2[1] = 0, lg2[2] = 1;
for (int i = 3; i <= n; ++i)
lg2[i] = lg2[i >> 1] + 1;
for (int i = 1; i <= n; ++i)
st[i][0] = p[i];
for (int i = 1; i <= 25; ++i){
int lim = n - (1 << i) + 1;
for (int j = 1; j <= lim; ++j)
st[j][i] = min(st[j][i - 1], st[j + (1 << i - 1)][i - 1]);
}
}
inline int query(int l, int r){
int i = lg2[r - l + 1];
return min(st[l][i], st[r - (1 << i) + 1][i]);
}
#define max(a,b) ((a>b)?a:b)
signed main(){
int n, t; scanf("%lld %lld", &n, &t);
for (int i = 1; i <= n; ++i)
scanf("%lld %lld", &d[i], &p[i - 1]), d[i] += d[i - 1];
init(n);
int pos = 0, eng = 0, cst = 0;
while (pos < n){
if (eng < 0){
puts("-1");
return 0;
}
int l = pos + 1, r = n, res = -1;
while (l <= r){
int mid = l + r >> 1;
if (query(pos + 1, mid) <= p[pos]) r = mid - 1, res = mid;
else l = mid + 1;
}
if (d[res] - d[pos] > t){
cst += (t - eng) * p[pos];
eng = t - (d[pos + 1] - d[pos]);
pos++;
}
else{
int tag = 0;
if (eng > d[res] - d[pos]) tag = eng - d[res] + d[pos];
cst += (d[res] - d[pos] - min(eng, d[res] - d[pos])) * p[pos];
eng = tag; pos = res;
}
}
printf("%lld", cst);
return 0;
}
[HG]走夜路 题解的更多相关文章
- 洛谷P1238 走迷宫题解
题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个数据来描述的,分别表示 ...
- 【UR #7】水题走四方 题解
链接:http://uoj.ac/problem/84 20分算法:萌萌的小爆搜,别搜进环里就行. 50分:我们考虑一下最优决策是什么样的.看似很显然的一点就是我们先让本体在原地不动,让分身去遍历子树 ...
- [HG]子树问题 题解
前言 模拟赛赛时SubtaskR3没开long long丢了20分. 题意简述 题目描述 对于一棵有根树(设其节点数为 \(n\) ,则节点编号从 \(1\) 至 \(n\) ),如果它满足所有非根节 ...
- [HG]腿部挂件 题解
前言 暴力跑的比正解快. 以下暴力(循环展开+fread读入输出优化) #include<cstdio> #pragma GCC optimize(3, "Ofast" ...
- [HG]提高组 题解
首先很容易想到暴力DP 设状态f[i][j]表示当前放了第i个数,最大的数为j的方案数. 然后根据转移推出实际上是在下图走路的方案数 \[ \left( \left( \begin{matrix} x ...
- HGOI 20191030am 题解
Problem A 腿部挂件 给出$n$个数的序列$a_i$,支持$T$次操作. 每次操作形如$x , l , r$,计算$\max_{i = l}^{r} (a_i \oplus x)$的值. 对于 ...
- Codeforces 刷水记录
Codeforces-566F 题目大意:给出一个有序数列a,这个数列中每两个数,如果满足一个数能整除另一个数,则这两个数中间是有一条边的,现在有这样的图,求最大联通子图. 题解:并不需要把图搞出来, ...
- durex-word
"(半夜没睡着) “你是不是饿了,哎呀我也饿了.”" "(聊到合拍处) “我和你有一万句me too想要说.”" "(异地恋) “我辞职,去你那儿吧! ...
- Codeforces Round #365 (Div. 2) Chris and Road
Chris and Road 题意: 给一个n个顶点的多边形的车,有速度v,人从0走到对面的w,人速度u,问人最快到w的时间是多少,车如果挡到人,人就不能走. 题解: 这题当时以为计算几何,所以就没做 ...
随机推荐
- 如何重装mysql8及初次修改密码
首先在设置里卸载旧版的mysql 然后把你之前的安装的mysql文件夹整个删掉 然后删除注册表的MySQL信息 安装新版的MySQL 新建并配置my-default.ini文件 如下: [mysqld ...
- 为什么 ConcurrentHashMap 的读操作不需要加锁?
现在人工智能非常火爆,很多朋友都想学,但是一般的教程都是为博硕生准备的,太难看懂了.最近发现了一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默.所以忍不住分享一下给大家 ConcurrentH ...
- ASP.NET Core WebApi使用Swagger生成API说明文档【xml注释版】
⒈新建ASP.NET Core WebAPi项目 ⒉添加 NuGet 包 Install-Package Swashbuckle.AspNetCore ⒊Startup中配置 using System ...
- php7.2.1 安装
yum -y install wget openssl* gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype ...
- Jquery 控制table中的checkbox 相关选中事件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- BASH的保护性编程技巧
BASH的保护性编程技巧 shell常用逻辑判断 -b file 若文件存在且是一个块特殊文件,则为真 -c file 若文件存在且是一个字符特殊文件,则为真 -d file 若文件存在且是一个目 ...
- LLVM源码安装教程
LLVM4.0源码安装教程 环境:ubuntu16.04 llvm-4.0 clang-4.0 步骤: 1.依赖库安装,注意llvm的编译对gcc版本和cmake版本有要求,请根据版本进行匹配 $ s ...
- Java操作FTP,从FTP上读取指定文件,把指定文件上传到FTP
需要添加的依赖 <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> ...
- nfs服务的配置
nfs服务 nfs简介 Network file system 网络文件系统.NFS server可以看作是一个 file server.它可以让你的pc通过网络将远端的nfs server共享出来的 ...
- uft 测试工具使用
选择 uft 自带小飞机 cs测试 开始设置 启动插件管理 选择测试 软件类型 cs bs 新建录制项目 各个功能按钮 添加测试程序工作路径 进入录制 保存录制 ...