P1725 琪露诺 题解

洛谷博客链接:https://www.luogu.com.cn/article/jelykwpn

温馨提示:这是一篇使用 set 优化 DP 的题解。

背景:前段有一场 ABC 的 D 题,如果使用 set 便可以很快地通过,但是身边的人有写 ST 表的,有写单调队列的,甚至还有写线段树的。再次拿到这道被称为单调队列优化 DP 的板子,我脑海中第一个出现的竟是使用 set 优化,于是便诞生了这篇题解。

d p i dp_i dpi 为到达第 i i i 个格子所获得的最大冰冻指数,初始 d p 0 dp_0 dp0 0 0 0 d p 1 ∼ d p n dp_1\sim dp_n dp1dpn 为负无穷。

由于第 i i i 个格子可以跳到 i + l ∼ i + r i+l\sim i+r i+li+r 个格子,所以 d p i dp_i dpi 可以由 d p i − r ∼ d p i − l dp_{i-r}\sim dp_{i-l} dpirdpil 转移而来。易得转移: d p i = max ⁡ j = i − r i − l d p j + a i dp_i=\max\limits_{j=i-r}^{i-l}dp_j+a_i dpi=j=irmaxildpj+ai

显然上面转移是 O ( n 2 ) O(n^2) O(n2) 的,考虑如何优化。发现 d p i dp_{i} dpi d p i − r ∼ d p i − l dp_{i-r}\sim dp_{i-l} dpirdpil 转移而来, d p i + 1 dp_{i+1} dpi+1 d p i − r − 1 ∼ d p i − l − 1 dp_{i-r-1}\sim dp_{i-l-1} dpir1dpil1 转移而来,有关区间只向右移动了一位,且我们只关心有关区间的最大值。

考虑用 set 维护有关区间,枚举到 i i i 时,set 维护的便是 d p i − r ∼ d p i − l dp_{i-r}\sim dp_{i-l} dpirdpil 这些值,从 set 中取最大值进行转移即可。

枚举到 i i i 时,在 set 中加入 d p i − l dp_{i-l} dpil,删去 d p i − r − 1 dp_{i-r-1} dpir1。单次操作时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

总时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)。虽然没有单调队列 O ( n ) O(n) O(n) 优秀,但比单调队列更加好写,且仍能轻松通过本题。

一些注意事项

  • d p i dp_i dpi 有可能出现相同的,因此我开的是 multiset
  • 删去 d p i − r − 1 dp_{i-r-1} dpir1 时,应写作 s.erase (s.find (dp[i - r - 1]))
  • 统计答案应从 d p n − r + 1 ∼ d p n dp_{n-r+1}\sim dp_n dpnr+1dpn 中取最大值。
  • set 中最大值为 *s.rbegin ()

代码:

#include <bits/stdc++.h>
#define int long long
#define INF 1e9 
using namespace std;
typedef long long LL;

const int N = 1e6 + 10;
int n, l, r, ans = -INF;
int a[N], dp[N];
multiset <int> s;

signed main ()
{
	ios::sync_with_stdio (false);
	cin.tie (0); cout.tie (0);
	
	cin >> n >> l >> r;
	for (int i = 0; i <= n; i++) cin >> a[i];
	memset (dp, -0x3f, sizeof dp);
	dp[0] = 0;
	for (int i = l; i <= n; i++) {
		if (i > r) s.erase (s.find (dp[i - r - 1]));
		s.insert (dp[i - l]); // 调整有关区间
		dp[i] = *s.rbegin () + a[i]; // 更新 dp 值
	}
	for (int i = n; i > n - r; i--) ans = max (ans, dp[i]); // 统计答案
	cout << ans;
	return 0;
}

相关推荐

  1. P1725 题解

    2024-07-23 08:26:03       37 阅读
  2. 题目 1752: 对称矩阵

    2024-07-23 08:26:03       41 阅读
  3. P9516 color 题解

    2024-07-23 08:26:03       67 阅读
  4. P6279 题解

    2024-07-23 08:26:03       56 阅读
  5. p8670题解

    2024-07-23 08:26:03       40 阅读
  6. [题解]P2895 流星雨

    2024-07-23 08:26:03       31 阅读
  7. 洛谷P1000-P1001题解

    2024-07-23 08:26:03       45 阅读
  8. P1161 开灯题解

    2024-07-23 08:26:03       62 阅读
  9. P1643 完美数 题解

    2024-07-23 08:26:03       64 阅读
  10. P1536 村村通题解

    2024-07-23 08:26:03       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-23 08:26:03       171 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-23 08:26:03       189 阅读
  3. 在Django里面运行非项目文件

    2024-07-23 08:26:03       157 阅读
  4. Python语言-面向对象

    2024-07-23 08:26:03       170 阅读

热门阅读

  1. Qt 实战(7)元对象系统 | 7.6、Q_DECLARE_METATYPE详解

    2024-07-23 08:26:03       33 阅读
  2. php 根据位置的经纬度计算距离

    2024-07-23 08:26:03       32 阅读
  3. 【git】切换到远程其他分支

    2024-07-23 08:26:03       34 阅读
  4. CentOS 6.8 中部署 Spring Boot 应用程序

    2024-07-23 08:26:03       35 阅读
  5. Mybatis-plus常用注解

    2024-07-23 08:26:03       28 阅读
  6. 华为OD机试 - 文件缓存系统——优先队列解法

    2024-07-23 08:26:03       37 阅读
  7. 计算机网络之数据链路层

    2024-07-23 08:26:03       29 阅读
  8. 今天是闭包,装饰器和案例

    2024-07-23 08:26:03       36 阅读
  9. 【Golang 面试基础题】每日 5 题(三)

    2024-07-23 08:26:03       35 阅读