首页 > 其他分享 >单调队列优化 dp

单调队列优化 dp

时间:2024-09-11 16:25:41浏览次数:10  
标签:状态 队列 sum int dp 优化 单调

1. 概念

单调队列优化的本质是借助单调性,及时排除不可能的决策,保持候选集合的秩序性。

2. 例题

P1714 切蛋糕

题目大意:

给定一个序列,找出长度不超过 \(m\) 的连续子序列,使得子序列中所有数的和最大。

思路:

要求区间和,首先求出前缀和,然后考虑朴素 dp,不难想到用 \(dp[i]\) 表示包含 \(a[i]\) 的连续子序列中的最大和,那么状态转移方程为:

\[dp[i] = \max\limits_{i - m\le j\le i - 1} \{sum[i] - sum[j]\} \]

所以朴素代码很快就能出炉:

#include <cstring>
#include <iostream>

using namespace std;

const int N = 500010;

int n, m;
int sum[N], dp[N];
int ans;

int main() {
    scanf("%d%d", &n, &m);
    int x;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &x);
        sum[i] = sum[i - 1] + x;
    }   
    memset(dp, -0x3f, sizeof dp);
    for(int i = 1; i <= n; i++) {
        for(int j = max(i - m + 1, 0); j <= i; j++)
            dp[i] = max(dp[i], sum[i] - sum[j - 1]);
        ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
    return 0;
}

时间复杂度为 \(O(n^2)\),不能够通过此题,考虑优化。

顺便提一句动态规划的优化思路:

一个原则:

在朴素代码上做等价变形。

三个方向:

  1. 优化状态设计,阶段和状态转移方程;
  2. 若有状态被多次计算或调用,则考虑加上记忆化搜索;
  3. 若有多层循环,考虑将与外层循环相关的变量看作定值,及时排除内层循环中的不可能决策或利用数据结构等方法优化找最值的过程,从而优化掉内层循环。

很显然,这道题我们选择方向 \(3\)。

容易发现,在外层循环到 \(i\) 时,\(sum[i]\) 是确定的,改变的只是 \(sum[j]\),所以,我们将状态转移方程整理一下,得:

\[dp[i] = sum[i] - \min\limits_{i - m\le j\le i - 1} \{sum[j]\} \]

所以,内层循环的作用其实是寻找 \(sum\) 数组中区间 \([i - m,i - 1]\) 的最小值,且当外层 \(i\) 变为 \(i+ 1\) 时,区间变成 \([i - m + 1,i]\),这意味着只需要将 \(j = i\) 加入候选决策集合并将 \(j = i - m\) 从决策集合中移除即可。

是不是和滑动窗口如出一辙?

所以我们可以用单调队列来优化这个找最小值的过程。

\(\texttt{Code:}\)

#include <cstring>
#include <iostream>

using namespace std;

const int N = 500010;

int n, m;
int sum[N];
int q[N], hh, tt = -1;
int ans = -0x3f3f3f3f;

int main() {
    scanf("%d%d", &n, &m);
    int x;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &x);
        sum[i] = sum[i - 1] + x;
    }
    for(int i = 1; i <= n; i++) {
        if(hh <= tt && i - m - 1 >= q[hh]) hh++;
        while(hh <= tt && sum[i - 1] <= sum[q[tt]]) tt--;
        q[++tt] = i - 1;
        ans = max(ans, sum[i] - sum[q[hh]]);
    }
    printf("%d\n", ans);
    return 0;
}

总结:

在状态转移方程中当前状态的所有值可以从上一个状态的某个连续的段的值得到,要对这个连续的段进行 RMQ 操作,相邻状态的段的左右区间满足非降的关系时,就可以使用单调队列优化 dp。

标签:状态,队列,sum,int,dp,优化,单调
From: https://www.cnblogs.com/Brilliant11001/p/18408438

相关文章

  • DPVO 代码剖析
    来自:https://github.com/princeton-vl/DPVO/blob/c0c5a104c9c58663aa9be62c3f125d5b52874f3e/dpvo/altcorr/correlation.py#L33classPatchLayer(torch.autograd.Function):@staticmethoddefforward(ctx,net,coords,radius):"""forwar......
  • Windows Server 2022 rdp
    继续水一篇:2022废弃了xddm转而使用wddm,rdp的渲染有比较大的变化。高版本的unreal又需要2022支持,被迫走上魔改windows以提升2022rdp环境下抓屏帧数的道路。测试代码来自https://github.com/robmikh/Win32CaptureSample,只手动添加了输出fps逻辑。patchwindows后能在[60,90]......
  • Wordpress 知名插件漏洞致百万网站面临接管风险
        流行的 WordPressLiteSpeedCache 插件中存在一个漏洞,可能允许攻击者检索用户cookie并可能接管网站。    该问题被跟踪为CVE-2024-44000,之所以存在,是因为该插件在用户登录请求后会在调试日志文件中包含set-cookie的HTTP响应标头。    ......
  • DP
    动态规划动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。三个条件:最优子结构,无后效性和子问题重叠。最优子结构证明问题最优解的第一个组成部分是做出一个选择;对于一个给定问题,在其可能的第一步选择中,假定你已经知道哪种选择才会得到最优解......
  • 搭建 WordPress 及常见问题与解决办法
    浪浪云活动链接:https://langlangy.cn/?i8afa52文章目录环境准备安装LAMP堆栈(Linux,Apache,MySQL,PHP)配置MySQL数据库安装WordPress配置WordPress常见问题及解决办法数据库连接错误白屏问题插件或主题冲突内存限制错误本文旨在介绍如何在服务器上搭......
  • 树形DP做题回顾(上)
    题目一 ​​​​Problem-2196大致意思就是求每个点为根的最大深度;对于这个问题,很快速的我们可以想到跑两次dfs,第一次预处理出以u为根的子树的第一,二深的深度,第二次dfs进行树形dp,从u->v时推出v的最大深度,用up[v]来存储;代码如下:注意分走到第一大和第二大的路径上的决策,以......
  • 虚树+树形dp
    虚树实际上是一颗浓缩子树;使用虚树的题目大部分具有查询的点有限,同时虚树构建的信息符合规则;做虚树的题目:步骤为先想出原树的暴力求解做法,然后构建虚树同时向其中添加有用信息(比如边权);虚树的构建过程:虚树的构建大致有两种,但是两种方式都与dfs序有关;首先解释为什么与dfs序有......
  • 线性dp:LeetCode122.买卖股票的最佳时机ll
    买卖股票本文所讲解的内容与LeetCode122.买卖股票的最佳时机ll,这道题题意相同,阅读完本文后可以自行挑战一下力扣链接题目叙述:给定一个长度为N的数组,数组中的第i个数字表示一个给定股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交......
  • 基于数组的循环队列
    基于数组的循环队列关键点在于:当元素总数超过队列长度后,出队、入队等行为如何避免数组越界问题。环绕数组的逻辑结构确实可以类比时钟,当指针走到最后一个刻度(比如12小时制的12点),再往前走时,指针会回到最开始的刻度(即1点),而不是继续前进到一个不存在的位置。 以12小时制时钟为......
  • Wordpress采集发布插件-免费下载
    推荐一款可以自动采集文章数据,并发布到Wordpress网站的Wordpress采集发布插件,支持对接简数采集器,火车头采集器,八爪鱼采集器,后羿采集器等大多数网页文章数据采集软件。Wordpress采集发布插件使用方法如下:1. 下载并安装Wordpress采集发布插件1.1 Wordpress采集发布插件免费下载......