Joyoi 綠豆蛙的歸宿

2022-03-18 02:48:34 字數 3270 閱讀 1444

題鏈:

題解:

期望dp,拓撲序

定義dp[i]表示從i點到n點的期望距離。

令cnt[u]表示u的出度。

顯然$$dp[u]=\sum_(dp[v]+e(邊權))* \frac$$

由於是個dag,所以拓撲排序後,從後向前dp即可。

題外話:為何不能正向dp:(希望聰明可愛的泥萌能看懂接下來的分析)

好吧,其實正向dp是可以的,但是沒有反向dp來的直接和簡單。

我們來看看弱弱的我當初覺得應該怎樣去正向dp:

定義dp[i]表示從1點到i點的期望距離。

那麼我們仿照之前反向dp的思路,我們找到當前v點的**點u,

顯然dp[v]肯定和dp[u]以及u的資訊有關。

那u對v的貢獻是不是就直接是$$dp[v]+=\frac$$

即我們希望上式得到:

1到v的期望距離dp[v] = (1到u的期望距離 + u到v的邊權)*(u到v的概率) [u為所有能到v的點]

為檢驗是否正確,我就試了幾個小例子:

1.乙個點沒有邊,答案為0,正確誒!(...)

2.兩個點,一條邊:1→ 2:3(箭頭兩頭為邊的起點和終點,3為邊權),答案為3,又正確了!(廢話)

3.三個點,3條邊:1→ 2:1,1→ 3:3,2→ 3:2,用腳趾頭也算得出來答案為3,可是程式喜聞樂見地輸出了乙個4。

???怎麼回事,dp**出現的問題?

經過一番分析,我找到了問題的根源,就處在dp轉移時加的邊權e那裡。

在詳細說明問題之前,我們先來看看通常倒著做的期望dp裡面的各個狀態的期望是如何實現遞推的,

即乙個狀態j的期望是如何通過計算的到其前繼狀態i的期望的。

假設狀態i轉移到狀態j的概率為p,代價為w,

用e(j)表示從狀態j到結束的期望,e(i)表示從狀態i到結束的期望,e(i→ j)表示狀態i下一步必須為狀態j,再到結束的期望。

由期望的定義可以知道:

e(j)=p1*w1+p2*w2+p3*w3+...+pn*wn(即第一種情況的概率*權值+第二種情況的概率*權值+...)

然後如果欽定i狀態必須轉移到j的話(代價為w),不那發現,

e(i→ j)=p1*(w1+w)+p2*(w2+w)+p3*(w3+w)+...+pn*(wn+w)

注意到了麼,從i→ j這個狀態到結束的情況數沒有變化,每種情況的概率也沒變,唯一的變化只是每種情況的權值都加了w。

而通常倒著做的dp,我們定義的狀態往往是表示從該狀態出發到結束的期望,即把該狀態看成了子問題的起點。

所以e(j)中所有的概率之和p1+p2+p3+...+pn = 1

那麼:e(i→ j)=p1*(w1+w)+p2*(w2+w)+p3*(w3+w)+...+pn*(wn+w)

=p1*w1+p2*w2+p3*w3+...+pn*wn + p1*w+p2*w+p3*w+..+pn*w

=e(j)+w

然後再把這個所謂的"欽定"改為"有p的概率從狀態i到狀態j",並累加進e(i):

e(i)+=p*e(i→ j)即e(i)+=p*(e(j)+w)

本題我們反向dp的轉移就是這麼推出來的。

那麼回到之前的問題,為何那樣正向dp就出錯了:

同樣地,我們設當前在i點,其前繼狀態為j點,從j轉移到i有p的概率,代價為w,

用e(j)表示從起點到j點的期望距離,e(i)表示從起點到i點的期望距離,e(j→ i)表示i點由j點而來的情況下,從起點到i點的期望距離。

我們用期望定義來寫出e(j)的構成:

e(j)=p1*w1+p2*w2+p2*w3+...+pn*wn

然後類似上面的步驟,我們欽定i狀態必須由j狀態轉移而來:

e(j→ i)=p1*(w1+w)+p2*(w2+w)+p3*(w3+w)+...+pn*(wn+w)

當然這裡還沒有任何問題,同樣的是情況數沒有變化,每種情況的概率也沒變,唯一的變化只是每種情況的權值都加了w。

我們繼續,嘗試化簡e(j→ i):

e(j→ i)=p1*(w1+w)+p2*(w2+w)+p3*(w3+w)+...+pn*(wn+w)

=p1*w1+p2*w2+p3*w3+...+pn*wn + p1*w+p2*w+p3*w+..+pn*w

=e(j)+p1*w+p2*w+p3*w+..+pn*w

然後上式等於e(j)+w麼?

問題就出在這裡。

當然不,因為這個dp定義下,每個dp狀態的起點都是1號點,也就是說,

e(j)裡面每種情況的概率應該是:第一種從1點到j的情況的概率p1,第二種從1點到j點的情況的概率p2,第三種p3...pn

但是顯然1點不會只到j點,(好吧除了之前搞笑用的第一組和第二組測試資料)

所以g(j) = p1+p2+p3+...+pn ≠ 1,

那麼順理成章地可以得到 e(j→ i) ≠ e(j) + w

也就可以得到,沒有所謂的"欽定"而是換成概率p,e(i)也不能加上p*(e(j)+w),

所以正向dp錯就錯在$dp[v]+=\frac$加的那個"dp[u]+e",

至於我之前說的正向dp也可以正確,泥萌應該也有點思路了吧:

因為構成**狀態的期望值的那些概率的和g(j)不等於1,所以不能直接加上權值w,

那麼我們就在dp的同時維護出從起點到每個狀態的概率g,

然後再看上面的e(j→ i) = e(j)+p1*w+p2*w+p3*w+..+pn*w = e(j) + g(j)*w

也就是說dp本題正向dp的轉移寫成$dp[v]+=\frac$就完成沒問題啦。

(實測ac,**在下面的注釋部分)

囉囉嗦嗦地說了1mol,希望對泥萌在理解正向和反向進行期望dp方面能有所幫助。

**:

#include#define maxn 100005

using namespace std;

struct edge

void adde(int u,int v,int w)

}e,f;

double dp[maxn];

int order[maxn],in[maxn],cnt[maxn];

int n,m,ont;

void bfs() }}

int main()

} cout

static double g[maxn]; g[1]=1;

for(int i=2;i<=n;i++)

} cout<*/ return 0;

}

綠豆蛙的歸宿

綠豆蛙的歸宿 time limit 10000ms memory limit 165536k total submit 3 accepted 1 case time limit 1000ms description 給出乙個有向無環的連通圖,起點為1終點為n,每條邊都有乙個長度。綠豆蛙從起點出發,走...

綠豆蛙的歸宿

兩種方法,正推和逆推 逆推 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...

綠豆蛙的歸宿

link emm,題目本身並不見得很難,主要是有乙個點必須理清楚。期望dp的計算需要遵守全期望公式,大概是 e sum limits i m p i times c i 也就是說你在搞清楚乙個東西對於期望的貢獻的同時還應該要知道它產生貢獻的概率。這也就回答了為什麼本題中只能逆推而不能順推的問題。畢竟...