题解-------CF372C Watching Fireworks is Fun
一道有趣的DP
题目大意
城镇中有$n$个位置,有$m$个烟花要放。第$i$个烟花放出的时间记为$t_{i}$,放出的位置记为$a_{i}$。如果烟花放出的时候,你处在位置$x$,那么你将收获$b_{i}- \left | a_{i}-x \right |$点快乐值。
初始你可在任意位置,你每个单位时间可以移动不大于$d$个单位距离。现在你需要最大化你能获得的快乐值。
思路:DP+单调队列+滚动数组
有一个显然的动态转移方程:
$f_{i,j}=max \left (f_{i,j},f_{i-1,k}+b_{i}- \left |a_{i}-j \right | \right )$
$f_{i,j}$表示在位置$j$放第$i$个烟花获得的最大值。
则$ans=max_{i=1}^{n}f_{m, i}$。
观察方程,可以看出$b_{i}$可以提出来,而$- \left |a_{i}-j \right |$的值在计算的过程中也是确定的,也可提出来。
最后的式子长这个样子
$f_{i,j}=min \left (f_{i,j},f_{i-1,k} \right )$
$ans=sum_{i=1}^{m}b_{i}-min_{i=1}^{n}f_{m, i}$
感觉可以,一看复杂度$O \left ( n^{2}m \right )$,T到飞起。
从上式中,可以看出$k$的范围是
$j- \left ( t_{i}-t_{i-1} \right ) *d \leq k \leq j+ \left ( t_{i}-t_{i-1} \right ) *d$
如何维护$k$的值?很明显,用单调队列维护,使得其能在均摊$0 \left (1 \right )$的时间复杂度内计算出$min \left (f_{i,j},f_{i-1,k} \right )$,没学的赶快学。
于是复杂度从$O \left ( n^{2}m \right )$降到了$O \left ( nm \right )$。
一看范围,150000。。。直接爆炸。
仔细观察,发现可以用滚动数组优化空间,能过。
代码
#include <iostream> #define RI register int
typedef long long ll;
const int N = 150001; using namespace std; template <class T>
inline void read(T &x) {
T f = 1; x = 0; char c = getchar();
while(c > '9' || c < '0') {
if(c == '-')
f = -f;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
x *= f;
} int n, m, d, t[2];
ll f[2][N], ans = 1e18 + 7, sum;
int l, r, q[N];
int p; inline int abs(int x) {
return x > 0 ? x : -x;
} inline ll min(ll x, ll y) {
return x > y ? y : x;
} int main() {
read(n), read(m), read(d);
for(RI i = 1; i <= m; i++) {
int a, b;
read(a), read(b), read(t[p ^ 1]);
sum += b;
ll len = ll(t[p ^ 1] - t[p]) * d;
l = 1, r = 0;
for(RI j = 1; j <= n; j++) {
while(l <= r && q[l] < j - len)
l++;
while(l <= r && f[p][q[r]] > f[p][j])
r--;
q[++r] = j;
f[p ^ 1][j] = f[p][q[l]] + abs(a - j);
}
l = 1, r = 0;
for(RI j = n; j >= 1; j--) {
while(l <= r && q[l] > j + len)
l++;
while(l <= r && f[p][q[r]] > f[p][j])
r--;
q[++r] = j;
f[p ^ 1][j] = min(f[p][q[l]] + abs(a - j), f[p ^ 1][j]);
}
p ^= 1;
}
for(RI i = 1; i <= n; i++)
ans = min(ans, f[p][i]);
printf("%lld\n", sum - ans);
return 0;
}
题解-------CF372C Watching Fireworks is Fun的更多相关文章
- CF372C Watching Fireworks is Fun(单调队列优化DP)
A festival will be held in a town's main street. There are n sections in the main street. The sectio ...
- 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces
题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...
- 【单调队列优化】[CF372C] Watching Fireworks is Fun
突然发现我可能单调队列都打不来了...我太菜了... 这道题显然有$$f[i][j]=min\{f[i-1][k]+\vert j-a[i] \vert\}$$ 则$ans=\sum_{i=1}^{m ...
- 单调队列+线性dp题Watching Fireworks is Fun (CF372C)
一.Watching Fireworks is Fun(紫题) 题目:一个城镇有n个区域,从左到右1编号为n,每个区域之间距离1个单位距离节日中有m个烟火要放,给定放的地点ai,时间ti当时你在x,那 ...
- Codeforces Round #219 (Div. 1) C. Watching Fireworks is Fun
C. Watching Fireworks is Fun time limit per test 4 seconds memory limit per test 256 megabytes input ...
- Codeforces Round #219 (Div. 2) E. Watching Fireworks is Fun
http://codeforces.com/contest/373/problem/E E. Watching Fireworks is Fun time limit per test 4 secon ...
- F - Watching Fireworks is Fun
C. Watching Fireworks is Fun 题目大意: 一个城镇有n个区域,从左到右1-n,每个区域之间距离1个单位距离.节日中有m个烟火要放,给定放的地点a[ i ].时间t[ i ] ...
- C. Watching Fireworks is Fun(Codeforces 372C)
C. Watching Fireworks is Fun time limit per test 4 seconds memory limit per test 256 megabytes input ...
- DP 优化方法合集
0. 前言 写完这篇文章后发现自己对于 DP 的优化一窍不通,所以补了补 DP 的一些优化,写篇 blog 总结一下. 1. 单调队列/单调栈优化 1.2 算法介绍 这应该算是最基础的 DP 优化方法 ...
随机推荐
- MacOS通过ssh连接基于Virtualbox的Ubuntu虚拟机
以前总是用Windows软件putty进行ssh连接,今天尝试使用macos. 实验环境:主机:macos 10.15.3 客户机:Ubuntu 18.04 默认情况下,Ubuntu没有安装SSH,需 ...
- 16 ~ express ~ 添加博客分类
一,创建表结构 /schemas/categories.js var mongoose = require('mongoose') module.exports = new mongoose.S ...
- 关于 python 中 虚拟环 virtualen境的操作
python3.X安装和pip安装方法 pip install -i https://pypi.douban.com/simple XXX 1.安装virtualenv pip install vir ...
- C++基础--引用的一点补充
这一篇是对引用的一点补充,内容基本上是来自<C++ primer plus>一书第八章的内容. 前面一篇介绍了引用的一点特点,这里补充一个,将引用用于类对象的时候,有一个体现继承的特征,就 ...
- hibernate.hbm.xml必须必须配置主键
hibernate.hbm.xml必须必须配置主键 <id name="XXid" type="java.lang.long" column=" ...
- JMP CALL RET
一.JMP指令(修改EIP的值)(第一个修改EIP的指令) 三种方法 :JMP 立即数 JMP 寄存器 JMP 内存 EIP 之前介绍过,EIP存放的值就是cpu下一次要执行的地址 1.之前学过要 ...
- JS高级学习笔记(10) 之 js 时怎么解析HTML标签的
DOM 节点类型 浏览器渲染过程 浏览器是怎么把HTML标签语言和JavaScript联系在一起的,这就是我们常说的DOM. 浏览器中的DOM解析器把HTML翻译成对象(object),然后JavaS ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习:for 循环
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 1, vm: PropTypes.instanceOf(VM).isRequired
子模块的文件引入父工程对象时,出现红色warning,提示传入的对象类型不是所要求的类型. 思路是父工程引用的JS包和子模块使用的包不是同一个包,解决办法是父工程和子工程都使用同一个包. resolv ...
- Springboot前后端分离中,后端拦截器拦截后,前端没有对应的返回码可以判断
项目登录流程如下 用户进入前端登录界面,输入账号密码等,输入完成之后前端发送请求到后端(拦截器不会拦截登录请求),后端验证账号密码等成功之后生成Token并存储到数据库,数据库中包含该Token过期时 ...