日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

维护无后效性的技巧——立即计算代价

發(fā)布時(shí)間:2024/9/5 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 维护无后效性的技巧——立即计算代价 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

無后效性是動(dòng)態(tài)規(guī)劃的一個(gè)基本特征之一,只有具備了無后效性的問題才可以使用動(dòng)態(tài)規(guī)劃求解。直觀上講,無后效性是指“現(xiàn)在不會(huì)影響未來”,或者說現(xiàn)在的決策不會(huì)影響未來如何決策。一個(gè)不具有無后效性的例子是矩陣尋路算法。設(shè)想一個(gè)0-1矩陣,尋找一條從1,1到n,n的最短路,不能使用下面的記憶化搜索算法:

FIND-PATH(x,y)if (out of matrix) return ∞if (x,y == n,n) return 0return dp[x][y] = min(FIND-PATH(x+1,y), FIND-PATH(x-1,y), FIND-PATH(x,y+1), FIND-PATH(x,y-1) )/*例如 1 0 0 0 1 0 1 1 1 1 1 1 1 0 0 1 這個(gè)算法會(huì)陷入無限遞歸 */

為什么這個(gè)算法無法正確結(jié)束呢?不難發(fā)現(xiàn),這個(gè)算法并沒有在決策(x,y)后要求以后不再遞歸計(jì)算(x,y),這就導(dǎo)致遞歸計(jì)算(x,y)的前提包括求解(x,y),算法會(huì)一直執(zhí)著于遞歸計(jì)算(x,y)而無法正確結(jié)束。
不難想到增加一個(gè)輔助數(shù)組now[][] = {0}。沒要計(jì)算一個(gè)(x,y)的時(shí)候就now[x][y] = 1防止落入死循環(huán)。

FIND-PATH(x,y)if (out of matrix or now[x][y]) return ∞if (x,y == n,n) return 0now[x][y] = 1// 鎖死(x,y)ans = min(FIND-PATH(x+1,y), FIND-PATH(x-1,y), FIND-PATH(x,y+1), FIND-PATH(x,y-1) )now[x][y] = 0// 釋放(x,y)return ans

顯然這個(gè)方法是正確的。那么能否直接加入dp[][]實(shí)現(xiàn)記憶化搜索呢?不行!考慮記憶化搜索(dp)的原理——無論何時(shí)計(jì)算dfs(x,y),得出的結(jié)果都是同一個(gè)值,因此不必從新計(jì)算。然而由于輔助數(shù)組now的加入,導(dǎo)致由于now的不同,不同時(shí)候詢問dfs(x,y)的結(jié)果可能不同。我們便稱這個(gè)問題違背無后效性原則,更準(zhǔn)確的,這個(gè)問題的子問題圖存在環(huán)。
很多dp問題的無后效性都是顯然的。然而一些時(shí)候,無后效性需要通過一些方法來維護(hù)。下面用幾個(gè)例子簡(jiǎn)單分析如何維護(hù)無后效性。

最優(yōu)二分檢索樹

  • 給定N個(gè)單調(diào)增數(shù)據(jù)a1..aN的權(quán)值f1..fN,構(gòu)造一棵二分檢索樹,ai的深度記作di,使得代價(jià)sum{di*fi}最小。

很顯然的區(qū)間dp題目,在區(qū)間i..j中枚舉一個(gè)k,遞歸計(jì)算i..k-1的代價(jià)和k+1..j的代價(jià),再加上k的代價(jià)即可。然而深度的計(jì)算遇到了麻煩。每一次試圖將序列分成兩部分時(shí),會(huì)使左右子樹每一個(gè)數(shù)據(jù)深度+1,這會(huì)影響到之后的決策。也就是說,對(duì)于同一個(gè)區(qū)間i..j來說,由于所處的深度不同,結(jié)果也不同。違背無后效性。
一個(gè)顯然的思路是更改狀態(tài),用dp[i][j][d]表示i..j深度為d時(shí)的代價(jià)。但是顯然這個(gè)方法復(fù)雜度為Θ(n^4),難以接受。
狀態(tài)不能更改,不如考慮決策。未進(jìn)行操作的序列每一個(gè)元素深度為0;每對(duì)i..j進(jìn)行一次決策,會(huì)導(dǎo)致其間的所有元素深度加一——這就是違背無后效性的一點(diǎn)。為了消除后效,我們必須一次性結(jié)算這次決策造成之后決策改變的總量。更直觀地,我們將di*fi看作fi連續(xù)加法,即 fi+fi+fi...di個(gè)fi,每進(jìn)行一個(gè)決策,當(dāng)前區(qū)間內(nèi)每一個(gè)元素ai代價(jià)都會(huì)加上fi,也就是當(dāng)前區(qū)間所有元素的代價(jià)和。dp方程如下:

dp[i,j] = min {dp[i,k-1] + dp[k+1,j]} + sum{a[i]..a[j]} i ≤ k ≤ j

用記憶化搜索實(shí)現(xiàn)即可,注意處理邊界。復(fù)雜度Θ(n^3)。據(jù)說可以優(yōu)化到Θ(n^2)不過我不會(huì)。

刪數(shù) ——tyvj

  • 對(duì)于一個(gè)數(shù)列a1..an,每次從左面和右面刪除一個(gè)數(shù),第i次刪去aj的代價(jià)是i*aj,求將數(shù)列全部刪除的最小代價(jià)。

和上一個(gè)題目有異曲同工之妙。這里不再分析為何需要維護(hù)無后效性,直接給出維護(hù)方法。
不妨稱題目中的i為一個(gè)元素aj的操作時(shí)間。每一次決策(刪除一個(gè)數(shù)),會(huì)導(dǎo)致剩下的所有數(shù)的操作時(shí)間加一;如果把代價(jià)i(j)*aj看作連續(xù)加法aj+aj+aj...i(j)個(gè)aj,每一次i加一會(huì)導(dǎo)致每一個(gè)未刪去元素aj的代價(jià)增加aj。dp[i,j]表示刪去ai..aj的最小代價(jià),則有方程:

dp[i,j] = min (dp[i+1,j], dp[i,j-1]) + sum{a[i]..a[j]}

任務(wù)安排——tyvj

N個(gè)任務(wù)排成一個(gè)序列在一臺(tái)機(jī)器上等待完成(順序不得改變),這N個(gè)任務(wù)被分成若干批,每批包含相鄰的若干任務(wù)。從時(shí)刻0開始,這些任務(wù)被分批加工,第i個(gè)任務(wù)單獨(dú)完成所需的時(shí)間是Ti。在每批任務(wù)開始前,機(jī)器需要啟動(dòng)時(shí)間S,而完成這批任務(wù)所需的時(shí)間是各個(gè)任務(wù)需要時(shí)間的總和(同一批任務(wù)將在同一時(shí)刻完成)。每個(gè)任務(wù)的費(fèi)用是它的完成時(shí)刻乘以一個(gè)費(fèi)用系數(shù)Fi。請(qǐng)確定一個(gè)分組方案,使得總費(fèi)用最小。
例如:S=1;T={1,3,4,2,1};F={3,2,3,3,4}。如果分組方案是{1,2}、{3}、{4,5},則完成時(shí)間分別為{5,5,10,14,14},費(fèi)用C={15,10,30,42,56},總費(fèi)用就是153。

輸入格式

  • 第一行是N(1<=N<=5000)。
  • 第二行是S(0<=S<=50)。
  • 下面N行每行有一對(duì)數(shù),分別為Ti和Fi,均為不大于100的正整數(shù),表示第i個(gè)任務(wù)單獨(dú)完成所需的時(shí)間是Ti及其費(fèi)用系數(shù)Fi。

輸出格式

  • 一個(gè)數(shù),最小的總費(fèi)用。

測(cè)試樣例

  • 輸入
5 1 1 3 3 2 4 3 2 3 1 4
  • 輸出
153

很顯然,由于順序不能改變,所以可以使用dp來求解。狀態(tài)是關(guān)鍵! .
雖然時(shí)間就是金錢,但是這里我們會(huì)把F值看作金錢,而時(shí)間看成金錢的單位。

費(fèi)用S = T * F,顯然S = F+F+F...(T個(gè)F)。 所以時(shí)間T每增加k,即T' = T+k,那么S' - S = kF。 我們便說:金錢又被收了k次。

我們?nèi)匀豢紤]每當(dāng)一個(gè)決策可能在未來產(chǎn)生消費(fèi)時(shí),就立刻預(yù)先支付這個(gè)價(jià)值從而維護(hù)無后效性。
分析問題: 每個(gè)任務(wù)的費(fèi)用是它的完成時(shí)刻乘以一個(gè)費(fèi)用系數(shù)Fi。不妨看成費(fèi)用系數(shù)Fi進(jìn)行了連續(xù)加法,每當(dāng)當(dāng)前決策之前的決策每使時(shí)間過去了1,就要在當(dāng)前決策的費(fèi)用中加上一個(gè)Fi;反過來,當(dāng)前的決策每使時(shí)間增加k分鐘,或者如開頭所說收了k次錢,就會(huì)使它以及其后的每一個(gè)任務(wù)的費(fèi)用加上Fi。由此得出dp方程:

dp[i]表示第i個(gè)到第n個(gè)任務(wù)所需的費(fèi)用 dp[i] = min{dp[j+1] + (sum{T[i..j]}+S) * sum{F[i..n]}} 其中 ij ≤ n 邊界是 dp[n+1]=0 目標(biāo)是 dp[1]

深刻理解這個(gè)方程,會(huì)受益匪淺。

總結(jié)

從以上三例可以找出一個(gè)共同點(diǎn)——都是有乘法的區(qū)間dp!事實(shí)上,乘法看成加法是立即計(jì)算代價(jià)一種很自然的方式。正是通過直接將決策造成的所有后效性直接計(jì)算出來, 使得不需要考慮是否需要為以前的決策買單。 立即計(jì)算代價(jià)無疑是一種省心的方法。

參考資料

《算法藝術(shù)與信息學(xué)競(jìng)賽》
《算法導(dǎo)論》
部分網(wǎng)上內(nèi)容,http://www.tyvj.cn 題解

轉(zhuǎn)載于:https://www.cnblogs.com/ljt12138/p/6684391.html

總結(jié)

以上是生活随笔為你收集整理的维护无后效性的技巧——立即计算代价的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。