DP的各類優化(動態規劃,決策單調性,斜率優化,帶權二分,單調棧,單調隊列)

前綴和優化

當DP過程當中須要反覆從一個求和式轉移的話,能夠先把它預處理一下。運算通常都要知足可減性。php

比較naive就不展開了。html

題目

【Todo】洛谷P2513 [HAOI2009]逆序對數列算法

【Done】洛谷P2511 [HAOI2008]木棍分割數據結構

【Done】洛谷P4099 [HEOI2013]SAO函數

【Done】NOIAC37 染色優化

單調隊列優化

前置技能:單調隊列(經典的問題模型:洛谷P1886 滑動窗口ui

用於優化形如\(f_i=\min/\max_{j=l_i}^{i-1}\{g_j\}+w_i\),且知足\(l_i\le l_{i+1}\)的轉移。spa

人話:對於序列中的每一個點,從其左側一段決策區間內的最值進行轉移,且決策區間隨着序列下標的增大也不斷右移(就像窗口向右滑動)。.net

\(j<k\),容易發現若是\(g_j\)劣於\(g_k\)的話,那麼當決策區間移動到\(k\)之後,\(j\)永遠不會成爲最優決策點,不再會被轉移了。指針

因而,咱們只要維護一個隊列,知足下標遞增,決策性遞減。咱們須要當前的隊首成爲最優決策點,那麼當隊首第一次超出了區間範圍(之後也就永遠超出了)就把它出隊。爲了保證單調性,隊尾新加入點以前,要先把隊列中比它劣的點依次從隊尾出隊。

題目

Sol.洛谷P1776 寶物篩選_NOI導刊2010提升(02)(就是多重揹包)

【Done】洛谷P2254 [NOI2005]瑰麗華爾茲

【Todo】洛谷P2569 [SCOI2010]股票交易

【Todo】洛谷P3572 [POI2014]PTA-Little Bird

【Todo】洛谷P3594 [POI2015]WIL-Wilcze doły

決策單調性

通常分兩類。不管是哪一類都須要細心發現決策之間的遞變規律。

一種是用於優化形如\(f_{i}=\min/\max w_{i,j}\)且對於每個\(i\)和它的最優決策點\(j\)都有單調性的方程。

這樣的方程對題目的性質要求較高(由於\(j\)是獨立的)。

只須要維護指針,按照單調性不斷尋找最優答案便可。

update:上面提到的這一種好像不在狹義的決策單調性的定義內。。。應該能夠叫雙指針優化。

另外一種是形如\(f_i=\min/\max_{j=1}^{i-1} g_j+w_{i,j}\),且記\(f_i\)的最優決策點爲\(p_i\)(也就是\(f_i\)\(g_{p_i}+w_{i,p_i}\)處轉移最優)若知足\(p_i\le p_{i+1}\),則該方程知足決策單調性。

在詩人小G的題解中蒟蒻用數形結合的思想討論了一種可能能夠快速準確地判斷一個轉移方程是否知足決策單調性的方法。

由於\(j\)不獨立了,因此咱們只能把有用的決策先存起來。

策略1——二分棧

咱們使用決策二分棧(一種單調棧)來維護全部有用的決策,其中棧頂是當前最優決策。

爲何叫二分棧呢?

咱們能夠把\(g_j+w_{i,j}\)視爲關於\(j\)的函數。由於決策單調,因此對於棧中的任意相鄰兩個決策點,咱們均可以經過二分找到一個臨界值\(k\),使得序列中在\(k\)以前的時候,其中一個做爲決策轉移到\(f_k\)更優,而\(k\)之後另外一個更優。能夠藉助函數圖像來理解這個過程。

咱們須要棧頂爲當前的最優解。而若是棧中有不止一個元素,則可能存在一個\(i\),使獲得\(i\)以後棧裏面的決策比棧頂優了。這個時候,如何快速判斷並彈掉棧頂呢?

上面提到的這個可二分的性質就派上用場了。對於當前的\(i\),若是當前棧頂下面與棧頂相鄰的決策在\(i\)以前就比棧頂更優了,就要把棧頂彈掉。

這是決策單調性的基本思想,具體的題目實現起來也不同。諸若有的題爲了擴展功能,還須要把單調棧換成單調隊列,等等。

策略2——分治

然而二分棧有一個侷限性,那就是必須能快速計算\(w_{i,j}\)。若是不能\(O(1)\)算的話,在求臨界值\(k\)的時候複雜度會嚴重退化。

既然轉移過程是單調而且離線的,咱們考慮分治。假設當前咱們求解一段區間\(f_{l,r}\),而全部\(f_{l,r}\)的最優決策點在\([L,R]\)之間。對於\([l,r]\)的中點\(mid\),咱們能夠暴力掃一遍\(L-mid\),找到它的最優決策點\(k\)。由於決策單調,因此\(f_{l,mid-1}\)的決策落在\([L,k]\)上,而\(f_{mid+1,r}\)的決策落在\([k,R]\)上,變成了兩個規模減半的小問題。

套用分治的複雜度分析,總的時間也是\(n\log n\)的。


兩種策略的代碼難度都不大呢~

廢話,DP固然是重在思惟啦!

題目

類型1

Sol.洛谷P1973 [NOI2011]Noi嘉年華

【Todo】洛谷P3724 [AH2017/HNOI2017]大佬

類型2

【Done】BZOJ4709 [Jsoi2011]檸檬

Sol.洛谷P3515 [POI2011]Lightning Conductor

Sol.洛谷P1912 [NOI2009]詩人小G

Sol.CF868F Yet Another Minimization Problem洛谷)(vjudge

斜率優化

與決策單調性有着說不清的聯繫。

仍然是轉移方程形如\(f_i=\min_{j=1}^{i-1}g_j+w_{i,j}\)\(\max\)同理)

考慮兩個決策\(j_1,j_2\),若是\(j_1\)\(j_2\)優,那麼\(g_{j_1}+w_{i,j_1}\le g_{j_2}+w_{i,j_2}\)

這時候根據題目特色把\(w\)展開,若是式子能化成\(\frac{y_{j_1}-y_{j_2}}{x_{j_1}-x_{j_2}}\le k_i\)的形式,那麼咱們把每一個決策當作點\((x_j,y_j)\)分佈在座標系上,而真正有用的決策點實際上造成了一個凸殼。(由相似線性規劃的尋找最優解的過程能夠發現)

上面這段很差理解?下面第一題的Sol對兩種理解斜率優化的方法作了更詳細的分析(最好看第二種,由於第一種有針對性,不通用)(有圖片喲qwq)

因而咱們用數據結構維護凸殼上的全部點,具體實現依題而定。

不論是什麼題,加入決策點的時候要保證斜率遞增/遞減。

若是\(x\)單調,能夠用單調棧維護凸殼,轉移時使用當前直線的斜率(線性規劃),在棧內二分最優解。

若是斜率\(k\)單調,那麼用單調隊列維護凸殼,隊首爲當前最優決策。轉移以前若是隊首不優就出隊。

引用MashiroSky學長的更完整的套路總結(他的總結戳這裏

  斜率單調暴力移指針
  斜率不單調二分找答案
  x座標單調開單調隊列
  x座標不單調開平衡樹|cdq分治

題目

Sol.洛谷P2900 [USACO08MAR]土地徵用Land Acquisition

【Todo】洛谷P3195 [HNOI2008]玩具裝箱TOY

Sol.洛谷P3628 [APIO2010]特別行動隊

【Todo】洛谷P4360 [CEOI2004]鋸木廠選址

【Todo】洛谷P2305 [NOI2014]購票

【Todo】洛谷P1721 [NOI2016]國王飲水記

DP凸優化/WQS二分/帶權二分

WQS的論文(在線)(下載

這種算法用來解決一類問題——有\(n\)個物品,規定以若干方式選擇物品有若干代價,須要在強制選出\(C\)個物品的前提下最大/最小化代價。

通常來講,適用此算法的題目還要有以下一些特色:(設關於\(x\)的函數\(g(x)\)爲強制選\(x\)個物品的最值)

  1. 咱們沒法直接求出\(g(C)\)的值(廢話,否則幹嗎不直接求);
  2. 咱們能夠直接求出\(g\)的最值,以及使\(g(x)\)取到最值的\(x\)
  3. \(g\)是一個凸函數。

蒟蒻再解釋這是個什麼東東也比不上Creeper_LKF大佬的blog來的清楚明白了。

但是,有沒有大佬和蒟蒻同樣以爲用二分斜率切凸包的這種思路有點很差理解呢?

受超級大佬學哥的啓發,蒟蒻想試着用原函數與導數的相互轉化來理解咱們尋找恰好選取\(C\)個物品時的最優解。

這是\(g(x)\)(上方藍色曲線)和\(g'(x)\)(下方紅色曲線)

\(C=7\),如今咱們的任務就是求出\(g(7)\)

顯然,由於\(g(x)\)是凸的,因此\(g'(x)\)是單調遞減的。咱們能夠求出如今\(g(x)\)的最值,有什麼特色呢?看看\(g'(x)\)\(x\)軸相交的地方,不就是在這個點處\(g(x)\)取到最值麼?

然而這個交點\(x=5\),不是咱們想要的。若是咱們能把函數膜改一下,使導函數的交點挪到\(x=7\),那該有多好!

\(f(x)=g(x)+kx\)\(k\)的現實意義是,咱們每多選一個物品,就要多付出\(k\)的代價。

\(k\)的函數意義又是什麼呢?咱們顯然能夠發現\(f'(x)=g'(x)+k\),至關於導函數向上平移了\(k\)個單位!而導函數是遞減的,若是咱們把它向上平移,那它與\(x\)軸的交點就會向右移了。等於說\(k\)越大交點的\(x\)也越大。這個樣子是可二分的。

因而咱們對\(k\)進行二分,\(k\)的值域就是導函數的值域。咱們作一遍DP,在原有的轉移基礎上,每多選一個物品還要額外加上\(k\)的代價。最後,咱們能夠求得\(f(x)\)的極值點,也就是\(f'(x)\)\(x\)軸的交點。若是這個交點\(x<C\)說明咱們仍需繼續調大\(k\),不然就是調小咯。

如今咱們試着模擬一下。一開始\(k\)等於\(0\)的時候交點\(x=5<C\),咱們就把\(k\)調大一點點。

圖中多了\(f(x)\)(上方綠色曲線)和\(f'(x)\)(下方橙色曲線)

如今的交點\(x=9\),又比\(7\)大了,咱們調小\(k\)

又通過若干調整,咱們終於使得交點落在了\(C\)這個位置。

那麼咱們要求出\(g(C)\)了。咱們如今求出的是\(f(C)\),只須要\(g(C)=f(C)-kC\)便可,等於說減掉函數圖像中\(f(x)\)\(g(x)\)\(C\)處的高度差。

看上去須要小數二分?不是這樣的。在實際的DP問題中\(x\)確定都是整數點,那麼\(g(x)\)確定是一段一段的折線,\(g'(x)\)就是一段一段的水平線,等於說取遍\(g'(x)\)的整數點的值就能取遍\(g'(x)\)的整個值域了。因而在整數內二分便可。

注意上面的\(g(x)\)是上凸的,若是\(g(x)\)下凸那麼\(g'(x)\)遞增,二分的方向還要變一下。

題目

Sol.洛谷P2619 [國家集訓隊2]Tree I(不是DP,但有助於理解帶權二分)

Sol.洛谷P4072 [SDOI2016]征途

【Done】洛谷P4383 [八省聯考2018]林克卡特樹lct

【Todo】BZOJ5311貞魚

【Todo】洛谷CF739E Gosha is hunting

相關文章
相關標籤/搜索