兩種方法,正推和逆推
逆推:\(dp[i]\)表示從\(i\)到\(n\)的期望,方程的轉移:對於一條從\(x\)到\(y\)邊
\(dp[x]=\sum\limits_^(dp[y]+edge[i])/oud[x]\)
正推:\(dp[i]\)表示從\(1\)到\(i\)的期望,\(g[i]\)表示從\(1\)到\(i\)的概率,方程的轉移:對於一條從\(x\)到\(y\)的邊
\(dp[y]=\sum\limits_^(dp[x]+edge[i]\times g[x])/oud[x]\)
why?
逆推:\(e(y)=p_1x_1+p_2x_2+\cdots\cdots+p_nx_n\)
\(e(x)=p_1(x_1+w)+p_2(x_2+w)+\cdots\cdots+p_n(x_n+w)=e(y)+\sum\limits_^np_i\times w=e(y)+w\)
正推:\(e(x)=p_1x_1+p_2x_2+\cdots\cdots+p_nx_n\)
\(e(y)=p_1(x_1+w)+p_2(x_2+w)+\cdots\cdots+p_n(x_n+w)=e(x)+\sum\limits_^np_i\times w\neq e(x)+w\)
code(正推):
#include#include#include#includeusing namespace std;
const int maxx=100010;
int oud[maxx],ind[maxx],ver[maxx<<1],nxt[maxx<<1],head[maxx],edge[maxx<<1];
double dp[maxx],g[maxx];
int tot,n,m;
inline void add(int x,int y,int z)
inline void topsort() }}
int main()
topsort();
printf("%.2lf",dp[n]);
return 0;
}
code2(逆推 )為了方便更新我們建了反圖,但是出度以原圖為準#include#include#include#includeusing namespace std;
const int maxx=100010;
int head[maxx],ver[maxx<<1],nxt[maxx<<1],edge[maxx<<1],ind[maxx],oud[maxx];
int tot,n,m;
double dp[maxx];
inline void add(int x,int y,int z)
inline void topsort() }}
int main()
topsort();
printf("%0.2lf",dp[1]);
return 0;
}
綠豆蛙的歸宿
綠豆蛙的歸宿 time limit 10000ms memory limit 165536k total submit 3 accepted 1 case time limit 1000ms description 給出乙個有向無環的連通圖,起點為1終點為n,每條邊都有乙個長度。綠豆蛙從起點出發,走...
綠豆蛙的歸宿
link emm,題目本身並不見得很難,主要是有乙個點必須理清楚。期望dp的計算需要遵守全期望公式,大概是 e sum limits i m p i times c i 也就是說你在搞清楚乙個東西對於期望的貢獻的同時還應該要知道它產生貢獻的概率。這也就回答了為什麼本題中只能逆推而不能順推的問題。畢竟...
Joyoi 綠豆蛙的歸宿
題鏈 題解 期望dp,拓撲序 定義dp i 表示從i點到n點的期望距離。令cnt u 表示u的出度。顯然 dp u sum dp v e 邊權 frac 由於是個dag,所以拓撲排序後,從後向前dp即可。題外話 為何不能正向dp 希望聰明可愛的泥萌能看懂接下來的分析 好吧,其實正向dp是可以的,但是...