期望&概率DP-bzoj3063

具體鏈接不發了,因爲涉及版權問題

Description

隨着新版百度空間的下線,Blog寵物綠豆蛙完成了它的使命,去尋找它新的歸宿。

給出一個有向無環的連通圖,起點爲1終點爲N,每條邊都有一個長度。綠豆蛙從起點出發,走向終點。
到達每一個頂點時,如果有K條離開該點的道路,綠豆蛙可以選擇任意一條道路離開該點,並且走向每條路的概率爲 1/K 。
現在綠豆蛙想知道,從起點走到終點的所經過的路徑總長度期望是多少?

Input

第一行: 兩個整數 N M,代表圖中有N個點、M條邊
第二行到第 1+M 行: 每行3個整數 a b c,代表從a到b有一條長度爲c的有向邊

Output


從起點到終點路徑總長度的期望值,四捨五入保留兩位小數。

 

Sample Input

4 4
1 2 1
1 3 2
2 3 3
3 4 4
 

Sample Output

7.00

Hint



對於100%的數據  N<=100000,M<=2*N

 

我們可以來看一個例圖

從1到4一共有四種走法,並且期望分別爲

1、2、3、4    1/3 * 1/2 * 1 * ( 1 + 4 + 3)

1、2、4         1/3 * 1/2 * (1 + 4)

1、4               1/3 * 5

1、3、4          1/3 * 1 + (2 + 3)

我們枚舉路徑 , 再挨個算期望 肯定會T掉,所以我們來觀察一下,路徑

1、2、3、4  

1、2、4

這兩條,其實他們起點我們都可以看做是2,而且1~2這個我們是可以不管的,那麼這兩個的期望就可以合併到一起來求

我們就可以得到

f[4] = 0

f[3] = (f[4] + 3) / 1

f[2] = (f[3] + 4) / 2 + (f[4] + 4) / 2

f[1] = (f[2] +1) / 3 + (f[3] + 2) / 3 + (f[4] + 5) / 3

那我們就可以根據記憶化來求了 dfs一下就可以了

另外這個題,還可以根據期望的線性性質來計算,也就是計算每個邊的貢獻,這裏就不寫了,下一道題來詳細寫一下


vector<pair<int,double> >v[maxn];
double f[maxn];
double dfs(int x){
    if(f[x] > -1.0) return f[x];
    f[x] = 0;
    for(auto d:v[x]){
        int to = d.fi,val = d.se;
        f[x] += (dfs(to) + val);
    }
    f[x] /= v[x].size();
    return f[x];
}
int main()
{
    int m;
    while(cin >> n >> m){
        for(int i = 1;i <= m;i++){
            int x,y;
            double z;cin >> x >> y >> z;
            v[x].pb(P(y,z));
        }MS1(f); f[n] = 0;
        dfs(1);
//        cout << f[1] << endl;
        wt(f[1],2);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章