「Note」DP 方向 - DP 优化
1. 单调队列优化 DP
1.1. 简介
当一个选手比你小还比你强,你就打不过他了。这是对单调队列简单形象的概括。
单调队列在转移的过程中不断排除不可能成为决策点的元素,使每次转移寻找决策点的时间复杂度降为 \(O(1)\)。一般地,可被单调队列优化的转移式可被写为如下形式:
\]
\]
其中需要满足 \(l_i\) 单调不降,\(A_i\) 是只与 \(i\) 有关的变量,\(B_j\) 是只与 \(j\) 有关的变量。
不难发现单调队列要维护的是 \(F_i+A_i\),每次 \(j1\) 入队时,若满足 \(F_{j1}+A_{j1}>F_{j0}+A_{j0}\) 则将 \(j0\) 弹出,直到不满足条件或者队列为空。
此时取队头元素,它一定满足在范围内最优,将其作为决策点即可。特殊地,有时需要特判队列为空的情况。
1.2. 常见技巧
大部分情况下,转移方程并不显著,因为在其中的贡献往往与 \(i,j\) 都有关,此时尝试将贡献转化为 \(A_j+B_i\) 的形式,然后在单调队列中维护 \(F_i+A_i\) 即可。
1.3. 例题
\(\color{limegreen}{P1776}\)(单调队列优化多重背包)
| \(v_i\) | \(w_i\) | \(c_i\) | \(F_{i,j}\) |
|---|---|---|---|
| 物品 \(i\) 的体积 | 物品 \(i\) 的价值 | 物品 \(i\) 的个数 | 前 \(i\) 个物品放入总体积为 \(j\) 的物品的最大价值 |
显著地,有以下转移方程:
\]
设 \(j'=j-k\times v_i\),在保证 \(i\) 不变的情况下,分别考虑每个 \(j'\) 对 \(j\) 的贡献,此时有 \(k=\frac{j-j'}{v_i}\)。此时 \(j,j'\) 在 \(\bmod v_i\) 的意义下同余,设 \(j=t\times v_i+r\) 其中 \(0\le r<v_i\),考虑将贡献拆分有 \(j'=j-k\times v_i,k=\left\lfloor\frac{j}{v_i}\right\rfloor-\left\lfloor\frac{j'}{v_i}\right\rfloor=t-\left\lfloor\frac{j'}{v_i}\right\rfloor\),将原方程改写:
\]
不难想到在枚举 \(r\) 的基础上,枚举 \(j\) 进行单调队列优化。
$\text{Code}$:
#define LL long long
#define UN unsigned
#include<bits/stdc++.h>
using namespace std;
//--------------------//
const int N=1e5+1;
int n,V;
int v[N],w[N],c[N];
int ans,f[N];
int head,tail;
int q[N][2];
//--------------------//
int main()
{
scanf("%d%d",&n,&V);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&w[i],&v[i],&c[i]);
for(int i=1;i<=n;i++)
for(int r=0;r<v[i];r++)
{
head=tail=1;
q[1][0]=r,q[1][1]=f[r];
for(int tem,t,j=r+v[i];j<=V;j+=v[i])
{
tem=f[j]-j/v[i]*w[i],t=j/v[i];
while(head<=tail&&q[head][0]<j-c[i]*v[i])
head++;
f[j]=max(f[j],q[head][1]+t*w[i]);
while(head<=tail&&q[tail][1]<tem)
tail--;
q[++tail][0]=j,q[tail][1]=tem;
}
}
for(int i=1;i<=V;i++)
ans=max(ans,f[i]);
printf("%d",ans);
return 0;
}
\(\color{royalblue}{P3089}\)
| \(x_i\) | \(p_i\) | \(F_{i,j}\) | \(now_i\) |
|---|---|---|---|
| 目标点 \(i\) 的坐标 | 目标点 \(i\) 的分数 | 跳至目标点 \(i\),上一个目标点是 \(j\) ,所能获得的最大分数 | 当前单调队列还未加入的最近位置 |
先考虑单方向的做法,显著地,按照 \(x_i\) 排序后有以下转移方程:
\]
我们发现当 \(i\) 固定时并不能直接用单调队列优化,因为维护的 \(\max\) 中存在两个不固定值 \(j,k\)。考虑固定 \(j\),当 \(i\) 上升时,\(k\) 的范围单调不减,此时可以用单调队列维护。
对于每一个 \(j\) 维护一个单调队列,用 \(now_j\) 记录还未进队的最近位置,每次枚举 \(i\) 时,将符合条件的 \(k\) 入队,并更新 \(now_j\)。
至于向另一方向跳的情况,将数轴左右翻转再做一遍 DP 即可。
\(\color{royalblue}{P4544}\)
| \(ka\) | \(e\) | \(x_i\) | \(c_i\) | \(v_i\) | \(f_{i,j}\) |
|---|---|---|---|---|---|
| 需要饲料总数 | 中点坐标 | 商店 \(i\) 坐标 | 商店 \(i\) 库存 | 商店 \(i\) 价格 | 走到商店 \(i\) 经过交易后得到 \(j\) 个饲料的最小消费 |
先按照 \(x_i\) 排序,显著地,转移方程:
\]
将其转化:
\]
显著的单调队列。其中需要注意的是初值的设置以及转移的始末位置。
x. 前置知识 决策单调性
x.1. 简介
决策单调性是一个优秀的性质,对于具有决策单调性的动态规划可以采用很多方法进行优化。
通常地,决策单调性体现在 1D 维度上。当 \(j<j'<i<i'\) 时,若 \(F_i\) 从 \(F_{j'}\) 转移过来,那么 \(F_i'\) 不可能从 \(F_j\) 转移过来,只可能从 \(F_j'\) 或之后的状态转移。这种性质可称之为决策单调性。
x.2. 四边形不等式
四边形不等式如下,在 \(a<b<c<d\) 的情况下 \(w(a,d)+w(b,c)>w(a,c)+w(b,d)\)。
设 \(F_i\) 由 \(F_j+w(i,j)\) 转移来,若满足四边形不等式则称其具有决策单调性。
证明略,待施工。
2. 斜率优化
2.1. 简介
当一个最优化 DP 的转移方程形如:
\]
\]
即其中有一些只关于 \(i,j\) 其中一个的项和一个关于 \(i,j\) 两个变量的项,可以考虑用斜率优化来解决。
先对原式进行化简。设 \(F_i\) 由 \(F_j\) 转移过来,有 \(F_i=F_j+A_i+B_j+a_i\times b_j\),移项得:
\]
设 \(y=F_j+B_j,x=b_j,k=a_i,b=A_i-F_i\),当 \(i\) 固定时,我们得到了一个 \(k\) 固定的一次函数,使其经过不同的 \((x,y)\)(与 \(j\) 有关),可以得到不同的截距 \(b\)(与 \(F_i\) 有关),其中取截距最大或最小,可以得到 \(F_i\) 的最大或最小值,因题而异。
具体地,我们维护一个凸包,取一次函数与切点为决策点。
2.2. 常见技巧
「Note」DP 方向 - DP 优化的更多相关文章
- LG3205/BZOJ1996 「HNOI2010」合唱队 区间DP
区间DP 区间DP: 显然是一个区间向左右拓展形成的下一个区间,具有包含关系,所以可以使用区间DP. 状态设计: 考虑和关路灯一样设计状态 因为不知道当前这个区间是从哪个区间拓展而来,即不知道这个区间 ...
- LOJ 6435 「PKUSC2018」星际穿越——DP+倍增 / 思路+主席树
题目:https://loj.ac/problem/6435 题解:https://www.cnblogs.com/HocRiser/p/9166459.html 自己要怎样才能想到怎么做呢…… dp ...
- loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治
loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...
- loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)
题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...
- 「洛谷5017」「NOIP2018」摆渡车【DP,经典好题】
前言 在考场被这个题搞自闭了,那个时候自己是真的太菜了.qwq 现在水平稍微高了一点,就过来切一下这一道\(DP\)经典好题. 附加一个题目链接:[洛谷] 正文 虽然题目非常的简短,但是解法有很多. ...
- LOJ3058. 「HNOI2019」白兔之舞 [DP,MTT]
LOJ 前置知识:任意长度NTT 普通NTT只能做\(2^k\)的循环卷积,尝试扩展成长度为\(n\)的循环卷积,保证模意义下\(\omega_n\)存在. 不管怎样还是要算点值.推式子: \[ \b ...
- LOJ 2304 「NOI2017」泳池——思路+DP+常系数线性齐次递推
题目:https://loj.ac/problem/2304 看了各种题解…… \( dp[i][j] \) 表示有 i 列.第 j 行及以下默认合法,第 j+1 行至少有一个非法格子的概率,满足最大 ...
- 逛公园「NOIP2017」最短路+DP
大家好我叫蒟蒻,这是我的第一篇信竞题解blog [题目描述] 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园 ...
- BZOJ1369/LG4395 「BOI2003」Gem 树形DP
问题描述 LG4395 BZOJ1369 题解 发现对于结点 \(x\) ,其父亲,自己,和所有的孩子权值不同,共 \(3\) 类,从贪心的角度考虑,肯定是填 \(1,2,3\) 这三种. 于是套路树 ...
- 「题解」:[组合数学][DP]:地精部落
拿到这道题秒懂题意:波动序列. 然鹅不会打.想了一节课,想打纯组合数学,结果找不到规律. 想的是先假设拍出一个序列,然后交换其中的元素求组合, 无奈没啥规律可循,显然不能一口气求出来(我说的是我没办法 ...
随机推荐
- BUGKU_PWN_OVERFLOW2_WP
WP_OVERFLOW2 拿到程序,首先放到我们的kali里面看看是多少位的程序,然后在看看有没有什么安全属性 64位程序,并且开启了RELRO,NX 也就是说,这道题我们需要使用ROP绕过 使用id ...
- RSA算法详解及相关数学原理解析
RSA算法详解及相关数学原理解析 前言 为了记录自己学习密码学的过程,也是为了便于个人应付相关课程的考核,故写此博客. 本博客总结了怎么用C++手搓一个RSA算法,以及补补欠缺的一些数学知识和可能 ...
- SecureCRT配置跳板机
跳板机(Jump Server),也称堡垒机,是一类可作为跳板批量操作远程设备的网络设备,是运系统管理员或运维人员常用的操作平台之一. 大家知道,在日常的开发中,有可能我们的本机不能够直接连线上的服务 ...
- SSH登录方式及如何防止SSH端口被扫
ssh登录服务器的方式有三种:密码登录,公钥登录,证书登录.同时,密码登录有被破解的风险,网络上也有很多在扫描ssh端口的主机. 比如: 这里175.178.62.36是一个来自广东的服务器,17次尝 ...
- 【Linux】2.3 Linux目录结构
基本介绍 linux 的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录"/",然后在此目录下再创建其他的目录. 深刻理解 linux 树状文件目录是非常重要的,这里 ...
- Hive SQL实现近N周的数据统计查询
文/朱季谦 先前遇到过一个需求,需要基于HIVE统计近N周范围的数据,例如,统计近7周范围的数据指标. 需要用HIVE SQL去实现该功能,而HIVE SQL并没有PostgreSQL那样例如通过函数 ...
- seata-server 1.3.0整合nacos,使用nacos做注册和配置中心
前言 关于seata版本的选择和更详细的安装,可以参考 SpringCloud Alibaba之Seata入门及踩坑 本篇博客是整合nacos,nacos直接下载安装解压运行就可以了. seata的下 ...
- CSP - J理论(1)
CSP-J理论(1) CSP-J理论合集跳转 目录 本目录中所有标题单击均可以快速跳转哦 一.排列组合与概率 $\ \ \ \ \ $1.排列 $\ \ \ \ \ $2.组合 $\ \ \ \ \ ...
- Asp.net mvc基础(二)Controller给View传递数据的方式
1.ViewData传值 步骤一:通过在控制器中以键值对的形式进行赋值 ViewData["键"] = 值 赋值: 调用: 2.ViewBag传值 ViewBag是dynamic类 ...
- JVM 垃圾回收调优的主要目标是什么?
JVM 垃圾回收调优的主要目标 JVM 垃圾回收调优的目标是为了提升应用的性能,优化垃圾回收过程中的停顿时间和吞吐量.调优的核心目标通常包括以下几点: 1. 减少垃圾回收的停顿时间 停顿时间(Stop ...