1. 程式人生 > 實用技巧 >「演算法筆記」期望 DP 入門

「演算法筆記」期望 DP 入門

一、數學期望

1. 由來

\(17\) 世紀,有一個賭徒向法國著名數學家帕斯卡挑戰,給他出了一道題目:甲乙兩個人賭博,他們兩人獲勝的機率相等,比賽規則是先勝三局者為贏家,一共進行五局,贏家可以獲得 \(100\) 法郎的獎勵。當比賽進行到第四局的時候,甲勝了兩局,乙勝了一局,這時由於某些原因中止了比賽,那麼如何分配這 \(100\) 法郎才比較公平?

甲輸掉後兩局的可能性只有 \(\frac{1}{2} \times \frac{1}{2}=\frac{1}{4}\),也就是說甲贏得後兩局或後兩局中任意贏一局的概率為 \(1-\frac{1}{4}=\frac{3}{4}\),甲有 \(75\%\)

的期望獲得 \(100\) 法郎;而乙期望贏得 \(100\) 法郎就得在後兩局均擊敗甲,乙連續贏得後兩局的概率為 \(\frac{1}{2}\times \frac{1}{2}=\frac{1}{4}\),即乙有 \(25\%\) 的期望獲得 \(100\) 法郎獎金。

可見,雖然不能再進行比賽,但依據上述可能性推斷,甲乙雙方最終勝利的客觀期望分別為 \(75\%\)\(25\%\),因此甲應分得獎金的 \(100\times 75\%=75\) (法郎),乙應分得獎金的的 \(100×25\%=25\) (法郎)。這個故事裡出現了“期望”這個詞,數學期望由此而來。(¿)

(摘自百度百科)

2. 定義

數學期望是實驗中每次可能結果的概率乘以其結果的綜合,它的定義式為:

\[E(X)=\sum\limits_{k=1}^\infty x_i p_i \]

其中 \(i\) 是所有可能發生的事件,\(x_i\) 為事件的權值,\(p_i\) 為事件發生的概率。

3. 性質

\(C\) 為一個常數, \(X\)\(Y\) 是兩個隨機變數。以下是數學期望的重要性質:

1.\(E(C)=C\)
2.\(E(CX)=CE(X)\)
3.\(E(X+Y)=E(X)+E(Y)\)
4. 當 \(X\)\(Y\) 相互獨立時,\(E(XY)=E(X)E(Y)\)

二、例題

1.SP1026 FAVDICE - Favorite Dice

題目大意:一個 \(n\) 面的骰子,求期望擲幾次能使得每一面都被擲到。\(n\leq 6000\)

Solution:

結論:\(1+\frac{n}{n-1}+\frac{n}{n-2}+...+n=\sum\limits_{i=1}^n \frac{n}{i}\)

\(f[i]\) 表示已經擲出 \(i\) 個不同的面,還期望擲多少次能使得每一面都被擲到。

顯然 \(f[n]=0\)

對於所有 \(f[i]\ (i\neq n)\),有兩種情況:

  • \(\frac{i}{n}\) 的概率擲到重複的面,則還需擲 \(f[i]\) 次。
  • \(\frac{n-i}{n}\) 的概率擲到新的面,則還需擲 \(f[i+1]\) 次。

\(f[i]=(\frac{i}{n} f[i]+\frac{n-i}{n} f[i+1])+1\)

整理得,\(f[i]=f[i+1]+\frac{n}{n-i}\)

因此 \(ans=f[0]=\sum\limits_{i=n-1}^{0} \frac{n}{n-i}=\sum\limits_{i=1}^n \frac{n}{i}\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n;
double ans;
signed main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n),ans=0;
        for(int i=1;i<=n;i++)
            ans+=1.0*n/i;
        printf("%.2lf\n",ans);
    }
    return 0;
}

2. BZOJ 1419 Red is good

題目大意:桌面上有 \(R\) 張紅牌和 \(B\) 張黑牌,隨機打亂順序後放在桌面上,開始一張一張地翻牌,翻到紅牌得到 \(1\) 美元,黑牌則付出 \(1\) 美元。可以隨時停止翻牌,在最優策略下平均能得到多少錢。\(0\leq R,B \leq 5000\)

Solution:

\(f[r][b]\) 表示剩下 \(r\) 張紅牌、\(b\) 張黑牌的期望收益。

首先考慮邊界情況。

\(r=0\),即目前已經沒有紅牌時,停止翻牌,則 \(f[r][b]=0\)。當 \(b=0\),即剩下的牌沒有黑牌時,肯定會把剩下的紅牌全部翻掉,則 \(f[r][b]=r\)

討論其他情況。

\(\frac{r}{r+b}\) 的概率翻到一張紅牌,並帶來 \(1\) 的收益;有 \(\frac{b}{r+b}\) 的概率翻到一張黑牌,並帶來 \(1\) 的損失。

那麼顯然\(f[r][b]=max(0,\frac{r}{r+b}(1+f[r-1][b])+\frac{b}{r+b}(-1+f[r][b-1])\)。因為我們採用的是最優策略,所以當此時的局面已經不足以帶來大於\(0\)的期望收益時,應該停止翻牌,所以最後還要和\(0\)取\(max\)。

由於卡空間,需要使用滾動陣列。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=5010;
int n,m;
double f[2][N],ans;
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int r=1;r<=n;r++){ 
        f[r%2][0]=1.0*r;
        for(int b=1;b<=m;b++)
            f[r%2][b]=max(0.0,1.0*r/(r+b)*(1+f[(r-1)%2][b])+1.0*b/(r+b)*(-1+f[r%2][b-1]));
    } 
    printf("%.6lf\n",1.0*floor(f[n%2][m]*1e6)/1e6);
    return 0;
}

3. BZOJ 4318 OSU!

題目大意:給出一串數,每個數字有 \(a[i]\) 的概率是 \(O\),這串數字的分數定義為每一段極長連續的 \(O\) 的長度的立方和,\(OXXOO\) 的分數就是 \(1^3+2^3=9\),求期望分數。\(N\leq 10^5\)

Solution:

\(y[i]\) 表示到 \(i\) 為止連續打出多少個 \(O\)

\(p=a[i]\) 的概率打出 \(O\),則有 \(p\) 的概率 \(y[i]=y[i-1]+1\);有 \(1-p\) 的概率打出的不是 \(O\),則有 \(1-p\) 的概率 \(y[i]=0\)

\(E(y[i])=E(p\times (y[i-1]+1))=p\times (E(y[i-1])+1)\)

因為 \((x+1)^3=x^3+3x^2+3x+1\),所以還需要維護平方和。每打出 \(1\)\(O\),答案 \((x+1)^3\) 比原答案 \(x^3\) 相比多了 \(3x^2+3x+1\)

\(E(y[i]^2)=E(p\times (y[i-1]+1)^2)=p\times (E(y[i-1]^2)+2\times E(y[i-1])+1)\)

可以分別用 \(f_1[i],f_2[i]\) 維護 \(E(y[i]),E(y[i]^2)\)

\(f_1[i]=p\times (f_1[i-1]+1)\)

\(f_2[i]=p\times(f_2[i-1]+2\times f_1[i-1]+1)\)

那麼 \(ans[i]=ans[i-1]+p\times (3\times f_2[i-1]+3\times f_1[i-1]+1)\),最終的答案為 \(ans[n]\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n;
double a[N],f1[N],f2[N],ans[N];
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf",&a[i]);
    for(int i=1;i<=n;i++){
        f1[i]=a[i]*(f1[i-1]+1);
        f2[i]=a[i]*(f2[i-1]+2*f1[i-1]+1);
        ans[i]=ans[i-1]+a[i]*(3*f2[i-1]+3*f1[i-1]+1);
    }
    printf("%.1lf\n",ans[n]);
    return 0;
} 

4. HDU 4035 Maze

題目大意:有一個樹形的迷宮,有 \(N\) 個房間以及 \(N-1\) 條通道將它們連通,一開始在 \(1\) 號房間,每進入一個房間 \(i\),有 \(kill[i]\) 的概率被陷阱殺死回到房間 \(1\),有 \(s[i]\) 的概率找到出口逃離迷宮,如果沒有找到出口也沒有被殺,那麼就在與該房間相連的通道中等概率隨機選一條走,求逃離迷宮所需要走的通道數的期望值。(如果不能逃離輸出impossible)。\(T\leq 30,N\le 10^4\)