dp优化总结

dp优化总结

一、滚动数组

典型的空间优化。

这应该是最最普通的一个优化了吧。。

对于某些状态转移第i个只需要用到第i-1个状态时,就可以用滚动数组,把第一维用0/1表示。

拓展1:

当一个状态转移要用到前m个转移时,我们依然可以滚起来,把第一维按模m的值滚起来。

拓展2:

若每一个决策可以选任意次(在一定限度下),那么我们可以借鉴完全背包的思路,把决策一个一个累计起来,起到优化时间的作用。(例题:NOIP2013 飞扬的小鸟

二、数据结构优化

1.单调队列

如果一个转移方程模型大致如下:

\(dp[i]=max\{dp[i-1],dp[i-2],\cdots ,dp[i-m]\}\)

如果我们枚举m,显然这会非常浪费时间,那么我们可以把这m个值压入到一个单调队列中,每次弹出最大值,这样就可以做到\(O(1)\)更新。

2.线段树/树状数组

如果一个转移方程模型大致如下:

\(dp[i]=max\{dp[j]\}j \in [i-L_i,i-1]\)其中,每个 \(L_i\) 不一定相同,那么显然单调队列就无法做到这点了,于是我们就需要用到线段树来维护\(dp\)数组的最大值,可以做到\(O(log n)\)更新。

当然,如果题目需要,我们还可以在线段树增加区间更新操作。(例题:ZJOI2010 基站选址 解析

三、决策单调性优化

如果一个转移方程模型大致如下:

\(dp[i]=max\{dp[i-1],dp[i-2],\cdots,dp[i-m]\}\)且\(dp\)数组中的值呈现单调性,那么我们可以直接在\(O(1)\)的时间内找出最值,进行更新。(这个跟单调队列有点类似)(例题:牛客网2019 Day4 T2 卖羊驼 解析

拓展1:斜率优化

拓展2:排序优化

如果某个状态值与物品放置顺序无关,只与其内部的某些值有关,当这些值涉及到两个或以上时,如果直接存入状态中,显然会MLE,同时可能还会TLE

那么,我们可以将物品按照某个值排个序,这样对于该值,决策时就会具有单调性,于是状态就可以少很多(例题:SHOI2006 书柜的尺寸 解析

原文地址:https://www.cnblogs.com/SillyTieT/p/11419275.html

时间: 2024-09-29 18:28:06

dp优化总结的相关文章

常见的DP优化类型

常见的DP优化类型 1单调队列直接优化 如果a[i]单调增的话,显然可以用减单调队列直接存f[j]进行优化. 2斜率不等式 即实现转移方程中的i,j分离.b单调减,a单调增(可选). 令: 在队首,如果g[j,k]>=-a[i],那么j优于k,而且以后j也优于k,因此k可以重队列中直接删去.在队尾,如果x<y<z,且g[x,y]<=g[y,z],也就是说只要y优于x一定可以得出z优于y的,我们就删去y. 经过队尾的筛选,我们在队列中得到的是一个斜率递减的下凸包,每次寻找从上往下被-

hdu5009 离散化+dp+优化

西安网络赛C题.先对大数据离散化,dp优化 #include<iostream> //G++ #include<vector> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<cmath> using namespace std; const int maxn=512

LCIS tyvj1071 DP优化

思路: f[i][j]表示n1串第i个与n2串第j个且以j结尾的LCIS长度. 很好想的一个DP. 然后难点是优化.这道题也算是用到了DP优化的一个经典类型吧. 可以这样说,这类DP优化的起因是发现重复计算了很多状态,比如本题k的那层循环. 然后就可以用maxl标记搞一下,将O(n^3)变成O(n^2). #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> usi

loj6171/bzoj4899 记忆的轮廊(期望dp+优化)

题目: https://loj.ac/problem/6171 分析: 设dp[i][j]表示从第i个点出发(正确节点),还可以有j个存档点(在i点使用一个存档机会),走到终点n的期望步数 那么 a[i][k]表示i点为存档点,从i点走到k点(正确节点)的期望步数(中间没有其它存档点) 那么a[i][j]可以递推预处理出 其中g[v]表示从一个错误节点v开始走,期望走g[v]步会读档 解方程可以解出 s[j-1]就是点j-1出去的所有错误儿子的g[v]之和 那么接下来只要知道如何求g[v]就行了

poj1088 滑雪(dfs、dp优化)

#include <iostream> #include <map> #include <string> #include <cstdio> #include <sstream> #include <cstring> #include <vector> #include <cmath> #define N 110 int a,b,step=0; int anw=0; int moun[N][N]; int dp

dp优化1——sgq(单调队列)

该文是对dp的提高(并非是dp入门,dp入门者请先参考其他文章) 有时候dp的复杂度也有点大...会被卡. 这几次blog大多数会讲dp优化. 回归noip2017PJT4.(题目可以自己去百度).就是个很好的案例.那题是个二分套dp如果dp不优化复杂度O(n^2logn)还能拿60分(CCF太仁慈了,如果是我直接给10分). 正解加上个单调队列(其实是sliding window)O(nlogn) 我们发现,此类dp是这样的 状态i是由[l,r]转移过来的.且i在向右移动的过程中,[l,r]一

7.14 单调栈 单调队列 +dp优化

单调栈和单调队列的定义具体看ppt了 模板: 单调队列 head =1; tail = 0; rep( i ,1 ,n ){ while( head <= tail && a[i] < dq[tail].first)tail--; while( head <= tail && dq[head].second < i-k+1) head++; dq[ ++tail ]={a[i] ,i}; 例题:https://vjudge.net/contest/3

HDU 5389 Zero Escape (MUT#8 dp优化)

[题目链接]:click here~~ [题目大意]: 题意: 给出n个人的id,有两个门,每个门有一个标号,我们记作a和b,现在我们要将n个人分成两组,进入两个门中,使得两部分人的标号的和(迭代的求,直至变成一位数,我们姑且叫做求"和"操作~)分别等于a和b,问有多少种分法. [思路]:比赛的时候还是学弟递推的方程,当时是dp三维dp[i][j]k]:分别表示枚举到第i位,A门,B门的状态,但是一直没想到怎么进一步优化,卡在100n的复杂度了 赛后看了一下题解,(虽然高中生写的题解看

BZOJ1010单调性DP优化

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 10707  Solved: 4445[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压 缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过 压缩后变成一维长度为Ci.为了方便整