【整理】簡單的數學期望和概率DP


  • 數學期望 P=Σ每一種狀態*對應的概率。
  • 因為不可能枚舉完所有的狀態,有時也不可能枚舉完,比如拋硬幣,有可能一直是正面,etc。在沒有接觸數學期望時看到數學期望的題可能會覺得很闊怕(因為我高中就是這么認為的,對不起何老板了QwQ),避之不及。 但是現在發現大多數題就是手動找公式或者DP推出即可,只要處理好邊界,然后寫好方程,代碼超級簡短。與常規的求解不同,數學期望經常逆向推出。
  • 比如常規的dp[x]可能表示到了x這一狀態有多少,最后答案是dp[n]。而數學期望的dp[x]一般表示到了x這一狀態還差多少,最后答案是dp[0]

具體的看下面的題型吧,看完應該就有感覺了。

  •  最后面幾道是DP,感覺和數學期望關系不大,不看也罷。

一:Uva12230Crossing Rivers (數學期望)

題目大意:
有個人每天要去公司上班,每次會經過N條河,家和公司的距離為D,默認在陸地的速度為1,
給出N條河的信息,包括起始坐標p,寬度L,以及船的速度v。船會往返在河的兩岸,人到達河岸時,
船的位置是隨機的(往返中)。問說人達到公司所需要的期望時間。
思路: 
1,過每條河最壞的情況是t=3*L/v; 即去的時候船剛剛走。
2,過沒條河最優的情況是t=L/v;    即去的時候船剛剛來。
3,由於船是均勻發布的,符合線性性質,所以平均下來,過每條河的時間t=2*L/v。

(是不是感覺看完后豁然開朗。。。。。。發自內心地說道:原來是尼瑪這樣一個題,當然這個題並不典型)

二:SPOJ Favorite Dice(數學期望)

題意:

甩一個n面的骰子,問每一面都被甩到的次數期望是多少。
思路:

比較簡單常見,公式:初始化dp[]=0;  dp[i]=i/n*dp[i]+(n-i)/n*dp[i+1]+1;  化簡逆推即可。  求的是dp[0];

 

三:SGU495Kids and Prizes(數學期望||概率DP||公式)

題意:

有n個獎品,m個人排隊來選禮物,對於每個人,他打開的盒子,可能有禮物,也有可能已經被之前的人取走了,然后把盒子放回原處。為最后m個人取走禮物的期望。
思路: 
排隊取,第1個人取到1個,dp[1]=1;后面的人dp[i]=p取到禮物盒子+dp前面的取到禮物盒子=(n-dp[i-1])/n + dp[i-1]; 當然,也可以化簡為公式 printf("%.10lf\n",n*1.0*(1-pow((n-1)*1.0/n,m))); 

 

四:ZOJ3640Help Me Escape(師傅逃亡系列•一) (我自己的逃亡三題)

題意:

師傅被妖怪抓走了。有n個妖怪,每個妖怪有一個固定的戰斗力c[],師傅也有一個初始戰斗力f0。
每天,師傅會隨機選擇一個妖怪決斗,如果打得贏ft
>c[],就可以逃出去,逃出去要t[]天,畢竟超人不會飛;
否則,師傅會不甘心,當天他會拿出秘籍練功,將自己變強,f(t+1)=f(t)+c[],第二天尋找下一次機會。
問師傅能夠逃脫可怕的妖怪,繼續追求去印度吃手抓餅的夢想的天數的數學期望day。
思路:

設dp[F]是戰斗力為F時,逃離的天數期望。(答案是dp[f])。則有公式。

dp[F]= Σ 1/n * t[i]              ,F>c[[i]

           +∑ 1/n * dp[F+c[i]]   ,F<=c[i]

(第一題是水的,這一題像樣一點,列方程。)

 

五:HDU4035 Maze(師傅逃亡系列•二)(循環型 經典的數學期望)

題意:

師傅又被抓了,師傅現在在一個里。第一天他在1號節點;對於每一個節點,
有三種可能,一是被妖怪殺死ki,二是被徒兒救走ei,三是第二天等概率地走到相鄰的一個節點。
問師傅被救走的天數的期望,不能被救走輸出“impossible”。
思路:

上一個題,由於是單調的,沒有后續性,所以可以記憶化搜索或者DP解決。
這個題存在后續性,舉個例子。如果求從s號節點逃出去的期望dp[s],那么dp[s]和s的子節點和s的父節點有關,而欲求s的子節點時,子節點又和父節點s有關。。。 這個時候就需要我們找一個辦法來排除后續性。大概就是找一個很牛逼的公式。這個公式本來是和后續性有關,但是公式之間抵消的后續性。
設 E[i]表示在結點i處,要走出迷宮所要走的邊數的期望。E[1]即為所求。

    葉子結點:
    E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);
         = ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei);

    非葉子結點:(m為與結點相連的邊數)
    E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );
         = ki*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei)/m*∑(E[child[i]]) + (1-ki-ei);
設對每個結點:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
對於非葉子結點i,設j為i的孩子結點,則
    ∑(E[child[i]]) = ∑E[j]
                   = ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
                   = ∑(Aj*E[1] + Bj*E[i] + Cj)
    帶入上面的式子得
    (1 - (1-ki-ei)/m*∑Bj)*E[i] = (ki+(1-ki-ei)/m*∑Aj)*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei) + (1-ki-ei)/m*∑Cj;
    由此可得
    Ai =        (ki+(1-ki-ei)/m*∑Aj)   / (1 - (1-ki-ei)/m*∑Bj);
    Bi =        (1-ki-ei)/m            / (1 - (1-ki-ei)/m*∑Bj);
    Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj);

    對於葉子結點
    Ai = ki;
    Bi = 1 - ki - ei;
    Ci = 1 - ki - ei;

    從葉子結點開始,直到算出 A1,B1,C1;

    E[1] = A1*E[1] + B1*0 + C1;
    所以
    E[1] = C1 / (1 - A1);
    若 A1趨近於1則無解...

 

六:HDU3853LOOPS (師傅逃亡系列•三)(基礎概率DP) 

題意:

你知道,師傅經常被抓,這次又被抓到一個矩陣里面,最開始他在Map[1][1],出口在Map[n][m];
每一次他會消耗兩顆神丹,然后每一個格子,有一定概率留在原地,有一定概率向下走一格,有一定概率向右走一格。。。求師傅逃出去的神丹消耗期望。
思路:

這次的逃亡很好想,沒有前兩次那樣需要逆推或者求公式。聰明的你不如手動算一下。實在不行還可以參考下面的題目。

 

七:ZOJ3551Bloodsucker (數學期望)

題意:

開始有一個吸血鬼,n-1個平民百姓。每天一個百姓被感染的概率可求,問每個人都變成吸血鬼的天數期望
思路:

一般期望題逆推,設dp[i]是目前已經有i個吸血鬼,所有人變成吸血鬼的期望。則dp[n]=0;答案是dp[1]。(注意這里dp代表的什么

每一個dp[i]的感染概率可求是p[]=2.0*(n-i)*i/(n-1)/n*p; 則可得遞推公式: dp[i] = (dp[i+1]*p[]+1)/p[];

 

八:ZOJ3329One Person Game(循環型 數學期望)

 題意:

有三個骰子,面值分別是k1,k2,k3。每次扔出的值之和加到ans上,問多少次才能ans>n;當然,當遇到k1=a,k2=b,k3=c時,ans=0;重新開始累加。
思路:

和之前第五題Maze一個題型。寫出的公式是有后續性的。我們需要弄一個遞推公式,消去后續性。(當然循環的話高斯消元也可以做。)
設dp[i]表示達到i分時到達目標狀態的期望,pk為投擲k分的概率,p0為回到0的概率
則dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1;
都和dp[0]有關系,而且dp[0]就是我們所求,為常數
設dp[i]=A[i]*dp[0]+B[i];
代入上述方程右邊得到:
dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1
     =(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1;
     明顯A[i]=(∑(pk*A[i+k])+p0)
     B[i]=∑(pk*B[i+k])+1
     先遞推求得A[0]和B[0].
     那么  dp[0]=B[0]/(1-A[0]);

大概就是這個樣子。  

 

九:CF 148D D. Bag of mice (概率DP||數學期望)

 

 題意:

一對情侶開房玩抓老鼠游戲,老鼠有黑白兩色,女的為先手,先抓到白老鼠勝。
特別的,男的每抓一只老鼠后,還會隨機放走一只老鼠。問女的贏的概率是多少。如果輸了,后果會很嚴重,當天晚上只能睡沙發。
思路:

dp[i][j]為當前狀態,有i只白老鼠,j只黑老鼠,女的贏的概率。那么dp[][] = 這一次贏 + 以后贏=   i/(i+j) +  。。。具體見代碼。

  

十:POJ3682King Arthur's Birthday Celebration(數學期望||概率DP)

題意:

有一個富豪,他決定每天撒錢,並且拋硬幣,第一天1塊錢,第二天3塊錢,第三天5塊,直到他拋到硬幣向上的數量為K。

求天數期望和錢期望。
思路:

天數期望dp很好求,公式一推,代碼一敲。錢期望money沒想出來,我開始想難道是用第x天結束的期望乘第x天的錢,累加,直到x天的期望乘錢小於0.0001

但是參考了下別人的公式,反正自己是沒想出來。 天數:dp[i]
=dp[i]*(1-p)+dp[i-1]*p+1,化簡:dp[i]=dp[i-1]+1/p; money:money[i] = p(money[i-1]+ 2 *(dp[i-1]+1)-1) + (1-p)(money[i] + 2 * (dp[i]+1)-1)。

化簡:money[i]=money[i-1]+2*dp[i-1]-2*dp[i]+(1+2*dp[i])/p; 問題: 可以用巴斯卡分布?二項分布???給數學跪了 http://blog.csdn.net/nmfloat/article/details/50650489

 

十一: POJ2151Check the difficulty of problems (組合數學||概率DP)

題意:

一套題,有T個題,M個人應考,已知每個人做來某題的概率。問X的概率。X滿足,每個考生至少做來一道題。至少有一人做的題不少於N道。
思路:

不算是很典型的概率DP,更像是一道簡單數學題。

可以把所有考生都至少做來一道題的概率減去 每個人都做來1到n-1道題的概率。

p=[(1-x11)*(1-x12)(..) ] * [(1-x21)*(1-x22)(..)]*[...]     -    [...]*[...] ,這樣的話,用組合數就ok了。

但是這里是用的DP是思路,先把考生與考題的關系求出來,p[i][j][k] 表示第i個考試前j個題會做k道的概率。再根據題意進行DP。

 

十二:HihoCoder1164 隨機斐波那契(概率DP) 



大家對斐波那契數列想必都很熟悉:

a0 = 1, a1 = 1, ai = ai-1 + ai-2,(i > 1)。

現在考慮如下生成的斐波那契數列:

a0 = 1, ai = aj + ak, i > 0, j, k從[0, i-1]的整數中隨機選出(j和k獨立)。

現在給定n,要求求出E(an),即各種可能的a數列中an的期望值。(1<=n<=500)
思路:
不說了,數據小,我暴力枚舉的。

 

十三:HihoCoder 1075 開鎖魔法III(概率DP+組合)

描述

一日,崔克茜來到小馬鎮表演魔法。

其中有一個節目是開鎖咒:舞台上有 n 個盒子,每個盒子中有一把鑰匙,對於每個盒子而言有且僅有一把鑰匙能打開它。
初始時,崔克茜將會隨機地選擇 k 個盒子用魔法將它們打開。崔克茜想知道最后所有盒子都被打開的概率。
1,每個盒子都有一個入度和一個出度,以之前二分圖拆點的經驗來看,必然會形成很多個環。

2,每個環至少選擇一個盒子。

3,每個環至少選擇一個盒子的組合數,聯想到母函數,組合數。

4.自由YY。可以DP,但是誤差可能大一些。可以全部求出來再除,這樣誤差小一些。

 (ps:學會了母函數再搞組合是要多一分靈感!彎的four)

 十四:BZOJ - 4318: OSU! (期望DP&Attention)

題意:一段連續長度為L的線段貢獻是L^3,求貢獻的期望。 (注意期望的平方和求方的期望不一樣
思路:此類期望題都是單獨算某一位的貢獻,假設前一位的連續長度為g[i-1],那么很明顯當前位的期望長度為 g[i]=(g[i-1]+1)*p[i];

則當前為的貢獻是add=g[i]^3-g[i-1]^3=3*g[i]^2-3*g[i]+1。 這三部分分別算期望即可。

   第一部分:3*g[i]^2,就是平方的期望(不僅僅是期望的平方那么簡單),令期望的平方為數組g2,則3g2[i]=3*(g2[i-1]+2*g[i-1]+1)*p[i];

   第二部分:-3*g[i],其期望=-3*(g[i-1]+1)*p[i]

   第三部分:   1,其期望=p[i]
 主要就是要注意期望的平方如何去算!

 

 -------------------------------------------------------------分界線-----------------------------------------------------------------------------

2019-05-12更新

由於上訴都是一些比較簡單的東西,而好像又容易被搜索到,所以加點干貨。

 

干貨一:    反復模擬,逼近答案。

(有的題目,由於大方向確定,我們只需要在小范圍內一層一層不斷逼近即可;或是隨機多次也能得到比較正確的結果。

 

CodeForces - 24D :Broken robot (高斯消元 隨機)

pro:給定N*M的矩陣,以及初始玩家位置。 規定玩家每次會等概率的向左走,向右走,向下走,問走到最后一行的期望。保留4位小數。

sol:可以列出方程,高斯消元即可,發現是三角矩陣,O(N^2)。  也可以用反復逼近答案。 反復做,dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0  為了使逼近效果更好,我每次先左一次,再右一次。   雖然 暴力但是效率也不差。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1010;
double dp[maxn][maxn]; int d[maxn];
int main()
{
    int N,M,x,y;
    scanf("%d%d%d%d",&N,&M,&x,&y);
    rep(i,1,M){
        d[i]=2;
        if(i>1) d[i]++;
        if(i<M) d[i]++;
    }
    rep(i,x+1,N){
        rep(t,1,20){
            rep(j,1,M) dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0;
            for(int j=M;j>=1;j--) dp[i][j]=(dp[i][j+1]+dp[i][j-1]+dp[i][j]+dp[i-1][j])/d[j]+1.0;
        }
    }
    printf("%.10lf\n",dp[N][y]);
    return 0;
}
View Code

 

干貨二:    Min-Max容斥。

(有的題目,數據量比較小,但是方程很難列出,我們可能要考慮容斥,min-max容斥是一種比較常見的容斥方式。 他解決問題的方式:假設有S個對象,求把所有東西都取到的期望,不直接求,而是通過求子集的期望,然后容斥得到結果。

 

HDU - 4336:Card Collector(min-max容斥求期望)

pro:題面不好看,題意很簡單,就是給定S個物品,然后每次取到物品i的概率為pi,∑pi<=1; 求把所有物品都至少取到一次的期望。

sol:  T是S的子集,我們得到每個子集T的期望,然后乘上容斥系數,累加起來就是答案。 假設我們dfs得到了S的子集T,並且得到至少取到這個子集的一個的概率p,則其期望為1/p;

#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
double p[maxn],ans; int N;
void dfs(int pos,double now,int opt)
{
    if(pos==N+1) {
        if(opt>0){
           if(opt&1) ans+=1.0/now;
           else ans-=1.0/now;
        }
        return ;
    }
    dfs(pos+1,now,opt);
    dfs(pos+1,now+p[pos],opt+1);
}
int main()
{
    while(~scanf("%d",&N)){
        for(int i=1;i<=N;i++) scanf("%lf",&p[i]);
        ans=0; dfs(1,0.0,0);
        printf("%.4lf\n",ans);
    }
    return 0;
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM