1. 程式人生 > >【概率DP入門】

【概率DP入門】

http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html

有關概率和期望問題的研究

摘要

在各類資訊學競賽中(尤其是ACM競賽中),經常出現一些與概率和期望有關的題目。這類題目需要較高的數學水平和一定的演算法技巧,必須經過仔細分析,選擇合適的數學模型和演算法才能順利的解決問題。本文就對這類題目的一些常見方法進行了研究。

數學基礎

這裡寫的數學基礎是有關概率和期望的一點簡單的計演算法則,雖然我們都很熟悉,但是有時也可能會忘記使用,所以在這裡列出來,也作為以後內容的基礎。

概率的運算

Ø 兩個互斥事件,發生任一個的概率等於兩個事件的概率和

Ø 對於不相關的事件或者分步進行的事件,可以使用乘法原則。

Ø 對於一般情況p(A+B)=p(A)+p(B)-p(AB)

期望的運算

Ø E(φ)= ΣφiPi,這是期望的定義,其中φi是一個取值,而Pi是取這個值的概率

Ø 期望有“線性”,也就是說對於不相關的兩個隨機變數φ和ξ,E(φ±ξ)=E(φ)±E(ξ);E(φξ)=E(φ)E(ξ);E(φ/ξ)=E(φ)/E(ξ)

Ø 在某些情況下,期望可以表示成一個無窮的等比數列,然後利用極限的思想來求。

當然,這些只是最基礎的知識,要解決好概率和期望的問題,還需要掌握一些組合數學的知識。

常用方法

方法1 直接計算

這種方法說起來很簡單,就是推匯出一個數學公式,然後通過程式來計算這個式子的值。這樣的題目在與概率和期望有關的題目中比例不小,但是由於它們大都需要一定的組合數學基礎,而一旦推匯出公式,對演算法的要求並不太高,而時間複雜度往往也比較低,所以這類問題不是本文的重點。有關內容可以在任何一本組合數學書中學到。

例一 百事世界盃之旅[1]

 “……在2003年6月之前購買的百事任何飲料的瓶蓋上都會有一個百事球星的名字。只要湊齊所有百事球星的名字,就可以參加百事世界盃之旅的抽獎活動,獲取球星揹包、隨身聽,更可以赴日韓觀看世界盃。還不趕快行動!……”

你關上電視,心想:假設有n個不同球星的名字,每個名字出現的概率相同,平均需要買幾瓶飲料才能湊齊所有的名字呢?

輸入輸出要求

輸入一個數字n,2≤n≤33,表示不同球星名字的個數。                                                            

輸出湊齊所有的名字平均需要購買的飲料瓶數。如果是一個整數則直接輸出。否則就用下面樣例中的格式分別輸出整數部分和小數部分。分數必須是不可約的。

樣例輸入和輸出

輸入

輸出

2

3

5

          5

11—------

         12

17

       340463

58 -----------------

        720720


[1] 題目來源 SHTSC2002 Day 1 Prob 2

分析 這是一道比較簡單的概率和期望問題。只要確定好計算方法,就可以很容易的得到公式。如果單獨考慮每一名球星,那麼就中了命題人的圈套。因為考慮單獨的一個球星的時候所買的“沒用”的飲料在考慮其他球星的時候可能會變成有用的。正確的思路是,假設現在已經有k個球星的名字,那麼要使球星的名字達到k+1個平均需要買多少瓶飲料?這是很容易計算的,是n/n-k。所以我們從沒有球星的名字開始,直到把所有的球星名字都湊齊,平均需要的飲料數(E)就可以計算出來:

ANS=n(1/1+1/2+1/3+....1/n)

由於題目的資料規模並不大,所以可以直接使用PASCAL的Comp或Int64(C/C++的long long)進行計算。而題目要求得到即約分數,只要在計算的時候使用分數並注意約分就可以了。

我的分析:

當有k個人的時候,抽到下一個的概率是n-k/n  所以平均需要n/n-k瓶才能買到下一個

所以ANS=n(1/1+1/2+1/3+....1/n)

這裡可以用分數直接計算

如果n很多 需要關於n的近似公式  0.57721566490153286060651209 + ln(n)

方法2 動態規劃

動態規劃是一種應用範圍很廣的方法,由於概率和期望具有前面提到過的一些性質(特別是期望的定義以及期望的“線性”性質),使我們可以在概率和期望之間建立一定的遞推關係,這樣就可以通過動態規劃來解決一些概率問題。

與其他方面的動態規劃一樣,合理的選擇狀態以及高效的狀態轉移方程是應用這種方法的關鍵,而狀態的選擇在這類問題中尤為重要。選擇合適的狀態不僅可以提高效率,而且可以保證動態規劃所必須的無後效性。而動態規劃的各種優化方法也可以應用。

概率和期望的最值問題也往往使用動態規劃的方法來解決。

例二 多米諾骨牌[1]

你試圖把一些多米諾骨牌排成直線,然後推倒它們。但是如果你在放骨牌的時候不小心把剛放的骨牌碰倒了,它就會把相臨的一串骨牌全都碰倒,而你的工作也被部分的破壞了。

比如你已經把骨牌擺成了DD__DxDDD_D的形狀,而想要在x這個位置再放一塊骨牌。它可能會把左邊的一塊骨牌或右邊的三塊骨牌碰倒,而你將不得不重新擺放這些骨牌。

這種失誤是無法避免的,但是你可以應用一種特殊的放骨牌方法來使骨牌更多的向一個方向

分析

首先應該明確怎樣找到最佳的擺放策略。我們可以考慮在位置i放最後一塊骨牌。顯然,i前面的i-1塊骨牌和i後面的n-i塊骨牌是互不影響的。所以我們假設擺放i-1塊骨牌需要的次數平均是(或說期望是)E1,擺放n-i塊骨牌需要的次數平均是E2。那麼我們擺放了這兩段之後,就要把最後一塊放上。這時如果把左邊的碰倒了,就只好重新擺放。右邊的也是同樣的道理。所以需要擺放的平均值(E)是:

E = E1 + E +

這個式子的推導並不困難,方法之一就是應用方程的思想(參見後面介紹的概率—期望系統)。

既然得到了這個式子,我們就可以通過動態規劃來得到最優的擺放方案。設Ei是擺放i塊骨牌所需要的最少期望次數,那麼狀態轉移方程是:

Ei ­= min{Ek + Ei-1-k­ + } (0≤k≤i-1)

這樣就得到了一個O(n2)的演算法。根據題目中的資料規模,最大的運算量是100*10002 = 108,雖然可以忍受,但是還是比較慢的,如果資料稍大一點就容易超時。

這就需要我們對動態規劃進行優化。

這是一個1D/1D的動態規劃,我們自然希望得到O(n)的演算法,而這種優化一般都是通過動態規劃的方程性質得到的。

觀察動態規劃的方程,我們可以發現,當k從0變化到i-1時第一項是不斷增大的,第二項是不斷減小的,第三項則是一個常數。因此整個函式一定是單峰的,這樣就可以通過二分的方法進行優化,複雜度已經降到了O(nlogn)。而事實上,E這個數列不但是單增的,而且是凹的(如果PlPr=0就不凹也不凸,但是這不影響這裡的討論),通過這個性質我們還可以證明決策使用的k一定是不減的(證明很簡單,略去)。這樣通過記錄上一次決策使用的k,就得到了一個(均攤的)O(n)的演算法。


[1] 題目來源 UVA 10529

方法3 迭代

動態規劃要求問題無後效性,而如果問題有不可避免的後效性,動態規劃就無能為力了。這時我們可以採用迭代的方法來進行計算。

當然,迭代也不是萬能的,它要求問題有收斂性而且收斂的速度要足夠快,而且要求的結果精度不要太高。對於同一規模的不同的輸入,迭代法的效率可能會有很大的改變,所以這種方法有可能因為遇到比較壞的資料而失效。

此外,迭代法也未必是要解決有後效性的問題,只要問題有收斂性,迭代都可以起到一定的作用,下面這道例題就沒有後效性,但是由於動態規劃的時間複雜度過高,所以採用了一種動態規劃和迭代混合的方法來解決。

例三 巧克力[1]

2100年,ACM牌巧克力將風靡全球。

“綠的,橘紅的,棕色的,紅的…”,彩色的糖衣可能是ACM巧克力最吸引人的地方。你一共見過多少種顏色?現在,據說ACM公司從一個24種顏色的調色盤中選擇顏色來裝飾他們的美味巧克力。

有一天,Sandy用一大包有五種顏色的巧克力玩了一個遊戲。每次他從包裡拿出一粒巧克力並把它放在桌上。如果有桌上有兩粒相同顏色的巧克力,他就把他們吃掉。他驚奇的發現大多數時候桌上都有2到3粒巧克力。

如果ACM巧克力有C(1≤C≤100)種顏色,在拿出了N(1≤N≤1000000)粒巧克力之後在桌上恰有M(1≤M≤1000000)粒的概率是多少?

分析

如果N不是那麼大的話,我們是很容易用動態規劃來解決此題,狀態轉移方程就是

Pi+1,k=Pi,k-1*(C-k-1)/C+Pi,k+1*(k+1)/C

其中Pi,k表示拿出了i粒巧克力後桌上剩餘M粒的概率(當然還要考慮一些邊界情況)。但是現在N可以達到1000000,如果直接動態規劃肯定是要超時的。

這個題的標準演算法是使用生成函式。也就是說把“桌上有m塊巧克力”轉化成“有m種巧克力取了奇數塊,其餘的都取偶數塊的取法”。所以就可以列出生成函式是,所以總的取法數就是xn的係數乘以n!和C(c,m),而概率就是總的取法數除以cn,然後通過進一步的代數分析來化簡解決。這種方法當然是很優秀的,複雜度是O(c2)。但是由於這道題的精度要求很低,迭代的方法也是可以達到目的的,而且複雜度也接近O(c2)。

這道題裡不會出現極大或極小的概率,一般來說這種情況下的收斂是比較快的。我們可以不斷的計算P的值,當它的變化不足以影響結果時就停止計算。當然這道題裡的收斂是分奇偶的(顯然桌上剩餘的巧克力數和拿出的巧克力數是同奇偶的),所以不能比較Pi和Pi-1,而要比較Pi和Pi-2,只要看到Pi和Pi-2差距小於一個定值(比如1e-5),而且i和N同奇偶,就可以停止動態規劃,因為此時繼續規劃下去所產生的不同已經不可能影響到要輸出的結果。經過實驗發現,最大的資料也只在幾百次迭代中就穩定了,這樣就將效率大大提高,滿足了題目的要求。


[1] 題目來源ZJU OnlineJudge 1363

方法4 概率—期望系統 

這個是我自創的,或許是由於不是很難吧,這個東西我在資料中沒有見到過。其實這就是方程的思想在概率和期望問題中的一個應用。

概率—期望系統的定義

概率—期望系統是一個帶權的有向圖。這個圖中的點代表一個事件,而如果點A與點B之間有一條權為p的邊,就表示A發生後,B緊接著發生的概率是p。初始的時候,有一個點(叫做初始點)代表的事件發生了,其他事件根據概率依次發生,每次只發生一個。求其他各個事件發生次數的期望。記時間A的發生次數期望為EA,A到B的邊權為PAB

一些限制

Ø 對任意的AB,PAB≤1

Ø 對於任意點A,,且對於系統中的所有點,至少有一個點使等號不成立。如果等號都成立的話這些事件將無窮無盡的發生下去,而概率—期望系統則變得沒有意義(此時期望或者是無窮大,或者是0)。

Ø 不能有指向初始點的邊,這是因為求解時我們把初始頂點的概率設為1。但是如果真的有這樣的邊,可以新增一個假點作為初始點,這個假點到真正的初始點有一條概率為1的邊。

概率—期望系統的求解

我們首先來看一種最簡單的概率—期望系統:有向無環圖的概率—期望系統。這種系統是很簡單的,因為它沒有後效性,所以可以通過動態規劃的方法在O(E)的時間內解決。許多使用動態規劃解決的概率—期望問題都是基於這類系統的。比如ZJU1022 Parallel Expectation就是這樣的。

但是在有些問題中(比如下面的例4),我們需要解決更一般的概率—期望系統。這時圖中含有圈,因而造成了後效性。我們當然可以用迭代法,而如果設第i次迭代時A的期望用Ei,A來表示,迭代的方程就是

通過若干次的迭代,就可以達到我們需要的精度。但是這個方法的效率是不穩定的,考慮這樣一個例子:A是起始點,PAB=1,PBC=1,PCB=0.99,這個例子的解是EA=1,EB=100, EC=100,但是如果用迭代的話需要很多次才能達到這個結果。而如果PCB=0.9999,那麼迭代法的速度就更加緩慢。

如何避免這種情況的出現呢?我們當然不能限制資料,而應該尋找更穩定的方法。考慮剛才迭代的過程,我們發現,在迭代的終點,近似的有

,這是一個方程,而這個方程的解其實就是我們所要求的解。我們只要把這個方程解出來,就可以得到精確的結果,而剛才說的迭代過程,實際上就是這個方程的求解過程(線性方程組的一種解法——Jacobi法就是這樣做的)。而求線性方程組的解,我們更常用的穩定演算法是高斯消元法,完全可以在這裡使用。這樣就得到了一種穩定而精確的解法:

首先根據概率—期望系統建立方程組,然後用高斯消元法去解,得到的結果就是我們要求的期望。這種演算法的時間複雜度是O(n3)。

當然這個複雜度是不很理想的,但是對於解方程組,我們沒有更簡單而高效的方法,所以這個演算法還是比較可取的。而迭代法也不能忽視,在概率不會出現極大或極小,而且邊又不多的時候,迭代法的效率往往會高於高斯消元。

此外,即使概率—期望系統中有環,也並不一定就不能使用動態規劃來解決,當環之間滿足一個偏序的時候,我們仍然可以使用等比數列求和的方法來進行處理,從而達到更好的複雜度。

例四 簡單遊戲[1]

所謂簡單遊戲,相信大家小時候都玩過,就是那種擲出股子子,然後按擲的步數走的遊戲。現在有一個n(1≤n≤100)個格子的遊戲,一些格子上有指令。指令分成若干種,如下:

Ø 0——空指令

Ø -1——陷阱,到了這裡後要擲出六才能繼續向前,注意不是向前六步,而是要再擲一次決定步數。

Ø -2——停一次

Ø 其它數字——轉移指令,走到數字所代表的格子

走到陷阱中是很難出來的,因此大家都不希望走到陷阱裡。玩一次遊戲走到陷阱裡的平均次數到底是多少呢?這個問題將由你來解決。

輸入:第一行n,表示遊戲的格數。第二行有n個數,表示每個格子的指令(第一個和最後一個都沒有指令)。注意如果某次走到的位置達到或超過最後一個格子,都表示遊戲結束。

輸出:走到陷阱裡的平均次數。保留3位小數,請儘量使用extended型別。

樣例:

輸入

輸出

4
0 -1 2 0

0.400

解釋:第一次走到陷阱裡,概率為1/3,第二次走到陷阱裡,概率為(1/3)*(1/6),第三次(1/3)*(1/6)2,……
由等比數列的求和公式中令n=無窮,可得概率之和為(1/3)/(1-(1/6))=2/5=0.4

分析

如果按照題目中的那個“解釋”的思路走,就不免中了圈套。題目中的轉向指令可以造成非常複雜的圈套圈的情況,用求極限的思想很難解決。

有了概率—期望系統,這個問題就並不困難了。我們只要構造一個圖就可以。把到達每個格子作為一個事件,每個事件如果沒有轉向指令就向後面的六個格子各連出一條概率為1/6的邊,如果有轉向指令就向轉向的那個格連一條概率為1的邊。的由於題目中沒有限制第一個格子不會有轉移指令指向,所以我們不能簡單的把第一個格子作為起始點,而應該做一個假起點,叫做0點,然後讓0到1有一條概率為1的邊就可以。例如樣例中的遊戲對應的圖和方程就是:


其中三角形箭頭表示概率是1,普通箭頭表示概率是1/6。

方程組:

E1 = 1

E2 = E1 + E3

E3 = E1 + E2

解得E2 = 0.4,這就是我們需要的結果。

對於任何一個遊戲,我們都可以按這種方法建立一個概率—期望系統,剩下的問題就是應用高斯消元法來解決就可以了。

當然我們不能忘記迭代法。但是容易看出,迭代法在這道題中可能遇到特殊設計的資料(一個典型的資料就是5個轉向指令連成一排,這種結構只要重複幾次就會造成答案非常大,可以達到105以上),對於這種資料,迭代是無法出解的。因此,本題選擇高斯消元是比較好的方法。

總結

本文對有關概率和期望的問題進行了一些研究,介紹了直接計算,動態規劃,迭代以及概率—期望系統四種常用方法。在實際解題時,只有具備紮實的數學基礎,靈活運用這些方法,才能順利的解決各種各樣的概率問題。


[1] 題目來源 原創



相關推薦

概率DP入門

http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html 有關概率和期望問題的研究 摘要 在各類資訊學競賽中(尤其是ACM競賽中),經常出現一些與概率和期望有關的題目。這類題目需要較高的數學水平和一定

數位dp入門HDU208962

ret main ont scanf size hdu2089 con %d tmp 為了我的點歪的技能樹…… 所以開始補一些sb的東西…… #include<bits/stdc++.h> typedef long long ll; using namespa

樹形dp入門沒有上司的舞會 @洛谷P1352

傳送門 題目描述 某大學有N個職員,編號為1~N。他們之間有從屬關係,也就是說他們的關係就像一棵以校長為根的樹,父結點就是子結點的直接上司。現在有個週年慶宴會,宴會每邀請來一個職員都會增加

數位dp入門51nod 1009 數字1的數量

給定一個十進位制正整數N,寫下從1開始,到N的所有正數,計算出其中出現所有1的個數。 N(1 <= N <= 10^9) dp[i] 表示 0 ~ (10 ^ i - 1) 中1的個數。 ten[i] 表示 10 ^ i 的值 pos 當前處理的位 num 當

NOIP2016提高換教室題解——作為概率DP入門

題目:luogu1850. 題目大意:給定v個教室,教室之間有e條無向邊邊,保證連通.現在有n組教室,每組有一個被欽定的教室和一個可以替換的教室,現在給你m次替換教室的機會,以及當你打算替換掉一組教室時成功的概率,讓你求最後依次經過你選擇的教室的期望路徑最小值. 我覺得我的題目大意好像解

概率dp滾動數組CDOJ1652 都市大飆車

ima 空間 pac names puts 都市 for 1.0 images 轉移方程很顯然。 因為是多段圖模型,所以可以滾動數組優化一維空間。 #include<cstdio> #include<cstring> using namespac

poj 2096 Collecting Bugs 概率DP逆向遞推求期望

tdi cor ros quick -a sim total 3.0 pla Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions

POJ3071 Football 概率dp

mem down matches pre opposite side instead losers rec 題目 Consider a single-elimination football tournament involving 2n teams, denoted 1,

BZOJ2337 [HNOI2011]XOR和路徑 概率dp + 高斯消元

但是 ++ clu alt HA exit rep 等於 找到 題目 題解 突然get到這樣路徑期望的題目八成是高斯消元 因為路徑上的dp往往具有後效性,這就形成了一個方程組 對於本題來說,直接對權值dp很難找到突破口 但是由於異或是位獨立的,我們考慮求出每一位的期望 設

LightOJ 1030 概率DP求期望

ble 重新 .html AR 格子 gin decimal tint i++ 借鑒自:https://www.cnblogs.com/keyboarder-zsq/p/6216762.html題意:n個格子,每個格子有一個值。從1開始,每次扔6個面的骰子,扔出幾點就往

HDU 2089 不要62數位DP入門

pan eps ava con 所有 數據 strong mon sub 不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi

bzoj 3029: 守衛者的挑戰概率dp

滾動數組 ios ble \n 轉移 spa min print amp 以後寫dp還是向後轉移吧……寫的把前面加起來的版本怎麽也調不過去 首先註意,因為地圖碎片只占1體積,所以>n,<-n的體積是沒用的,所以就可以把體積降到n級別,然後用這場勝負像後轉移即可,

概率DP+矩陣快速冪 POJ - 3744 Scout YYF I

Scout YYF I  POJ - 3744  YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. Afte

Bag of mice概率DP

概率DP與期望DP不同,這個是正序的,接下來上一下我的思路,先上題: Alice和Bob正在玩一個遊戲: 一個袋子裡一開始裝著w個白球和b個黑球。Alice和Bob輪流隨機抽出一個球(Alice先手)。如果抽出的球是白色的,則抽出這個球的人獲勝。每當一個球被Bob取出後,

codeforces 148DBag of mice概率dp記憶化

【連結】 【題意】 原來袋子裡有w只白鼠和b只黑鼠 ,龍和王妃輪流從袋子裡抓老鼠。 誰先抓到白色老鼠誰就贏。 王妃每次抓一隻老鼠,龍每次抓完一隻老鼠之後會有一隻老鼠跑出來。 每次抓老鼠和跑出來的老鼠都是隨機的。 如果兩個人都沒有抓到白色老鼠則龍贏。王妃先抓。

DP概率與期望2018國慶三校聯考D3T2

題意: 分析: #include<cstdio> #include<cstring> #include<algorithm> #include<cma

NYOJ:01串 DP入門

01串 時間限制:1000 ms  |  記憶體限制:65535 KB  難度:2 描述  ACM的zyc在研究01串,他知道某一01串的長度,但他想知道不含有“11”子串的這種長度的01

BZOJ2246[SDOI2011]迷宮探險搜尋概率DP

最後一組資料沒過,也不知道啥原因,打了發表(pia) 大體思路是,先搜尋出每個狀態下每個陷阱有害的概率,然後就可以跑dp了。 搜尋時,每個陷阱有三種狀態,0無害,1有害,2未遍歷。那麼用一個三進位制來表示狀態。 搜尋到一種狀態now,然後再列舉狀態轉移。 設wx[now