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 书柜的尺寸 解析)