1. 程式人生 > 其它 >noip模擬19/20

noip模擬19/20

這兩場考試大部分的題都考過,然鵝有的 \(trick\) 忘了,有的當時咕了(雖然現在還咕著

首先是 \(v\) 這道題需要加一個小優化,對於較小的狀態應該直接用陣列記錄,較大的再用 map 記

然後就是這個神奇的 \(dp\) 題:


A. 玩具

考場上只會暴搜,胡了一個 hash 還給掛了
正解是神奇的 \(dp\)

首先核心是 \(f[i][j]\) 表示 \(i\) 個點的樹深度為 \(j\) 的概率,那麼期望即概率乘深度之和
考慮這個怎麼轉移:
如果想辦法從 \(f[i-1][k]\) 轉移,可以發現這個狀態是不完備的,因為不知道 \(i-1\) 個點深度為 \(k\) 時各個深度的點各有多少個,那麼加在每個深度的概率是不相同的
那麼考慮這棵樹最後加入的點是樹頂那個點
因為樹頂那個點加入前整個的深度是固定的為 \(j-1\)

那麼問題又來了,如果加入的是樹頂,那麼原來所有的子樹將形成一個森林,顯然還需要一個變數維護森林的狀態
那麼設 \(g[i][j]\) 表示 \(i\) 個點的森林深度為 \(j\) 的概率,那麼有

\[f[i][j]=g[i-1][j-1] \]

接著考慮 \(g\) 的轉移,可以想到從一部點形成的樹外加另外的點形成森林來轉移
假設樹的大小為 \(k\),那麼一部分是 \(f[i][k]\),發現另一部分的深度是不確定的,只要小於等於 \(j\) 即可

說明狀態設計的有問題,那麼設計成深度小於等於 \(j\) 就好了
\(f\) 的轉移還是一樣的
然後再看 \(g\) 的轉移,發現還是有 \(bug\)

,因為總共有 \(j\) 個點,有 \(k\) 個點在第一棵樹裡,這是有概率的,那麼繼續打補丁——設 \(dp[i][j]\) 表示 \(i\) 個點的森林有 \(j\) 個點在第一棵樹的概率
考慮轉移,從 \(dp[i-1][]\) 轉移而來,分為新加的點在不在第一棵樹裡兩種情況,方程式為:

\[dp[i][j]=dp[i-1][j-1] * \frac{j-1}{i}+dp[i-1][j] * \frac{i-j}{i} \]

這裡需要注意看似上一種情況共可以向 \(i-1\) 個點連邊,為什麼分母上是 \(i\) 呢?
因為漏掉了一種情況就是新加的這個點其實是可以自成一棵樹的,所以沒有問題

這回終於可以轉移 \(g\) 了:

\[g[i][j]=\sum_{k=1}^{i} f[i][k]*g[i][i-k]*dp[i][k] \]

最後是統計答案,由於狀態設計的是字首和形式,那麼答案需要減一下,即:

\[\sum_{i=1}^{n} (f[n][i]-f[n][i-1])*i \]