传送门

一道有趣的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的更多相关文章

  1. 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 ...

  2. 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces

    题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...

  3. 【单调队列优化】[CF372C] Watching Fireworks is Fun

    突然发现我可能单调队列都打不来了...我太菜了... 这道题显然有$$f[i][j]=min\{f[i-1][k]+\vert j-a[i] \vert\}$$ 则$ans=\sum_{i=1}^{m ...

  4. 单调队列+线性dp题Watching Fireworks is Fun (CF372C)

    一.Watching Fireworks is Fun(紫题) 题目:一个城镇有n个区域,从左到右1编号为n,每个区域之间距离1个单位距离节日中有m个烟火要放,给定放的地点ai,时间ti当时你在x,那 ...

  5. 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 ...

  6. 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 ...

  7. F - Watching Fireworks is Fun

    C. Watching Fireworks is Fun 题目大意: 一个城镇有n个区域,从左到右1-n,每个区域之间距离1个单位距离.节日中有m个烟火要放,给定放的地点a[ i ].时间t[ i ] ...

  8. 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 ...

  9. DP 优化方法合集

    0. 前言 写完这篇文章后发现自己对于 DP 的优化一窍不通,所以补了补 DP 的一些优化,写篇 blog 总结一下. 1. 单调队列/单调栈优化 1.2 算法介绍 这应该算是最基础的 DP 优化方法 ...

随机推荐

  1. java虚拟机之JVM生命周期

    java生命周期分为以下三部分:启动,运行,消亡. 启动.启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的 ...

  2. 对spring中IOC和AOP的理解

    IOC:控制反转也叫依赖注入.利用了工厂模式. 为了方便理解,分解成每条以便记忆.  1.将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器 ...

  3. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring Bean的配置及常用属性

    作为 Spring 核心机制的依赖注入,改变了传统的编程习惯,对组件的实例化不再由应用程序完成,转而交由 Spring 容器完成,在需要时注入应用程序中,从而对组件之间依赖关系进行了解耦.这一切都离不 ...

  4. PAT Advanced 1076 Forwards on Weibo (30) [图的遍历,BFS,DFS]

    题目 Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and ...

  5. VS.NET中的常用控件和类型的命名规范

    表1  命名规范 VS名称 简写 VS名称 简写 数据类型 Array arr Boolean bln Byte byt Char Chr Date Time dtm Decimal dtm Doub ...

  6. 【Linux】linux磁盘管理

    在服务器管理中,我们会关心硬盘用了多少,还有多少剩余空间,哪些文件占用空间最大等等.以便我们在合适的时机为服务器添加硬盘分区以及管理磁盘文件等操作,让磁盘的利用率最大化,现在我们看下linux系统中和 ...

  7. P2P平台被清盘后,你会怎样捍卫自身利益?

    近段时间,P2P平台爆雷不断.很多交易金额过百亿的大型P2P平台也"晚节不保",跑路的跑路.倒闭的倒闭.清盘的清盘.从爆火到爆雷,P2P平台正应了那句话,"眼见他起高楼, ...

  8. bzoj4316小C的独立集(dfs树/仙人掌+DP)

    本题有两种写法,dfs树上DP和仙人掌DP. 先考虑dfs树DP. 什么是dfs树?其实是对于一棵仙人掌,dfs后形成生成树,找出非树边(即返祖边),然后dfs后每条返祖边+其所覆盖的链构成了一个环( ...

  9. pytorch 自动求梯度

    自动求梯度 在深度学习中,我们经常需要对函数求梯度(gradient).PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图,并执行反向传播.本节将介绍如何使用autogra ...

  10. Linux 文件上传

    Linux 文件上传操作 SecureCRT与linux互相上传和下载文件 1. 需要上传或者下载,需要使用rz和sz命令. 2. 如果linux上没有这两个命令工具,则需要先安装.可以使用yum安装 ...