嗯,noip歷年真題什麼的,到處都有,抓一道就是三四倍經驗題,我就不寫題目描述了23333
偷個懶一定不會被人發現的
事實上,這是我第一次做概率與期望dp的題目,不是很懂套路,然後就想了很久很久,沒什麼太多的頭緒。首先我覺得應該是用f[i][j]儲存前i個時間段,申請換j次課,期望收穫到的疲勞值。但是注意到這樣的狀態還是很複雜難以轉移,因為狀態轉移後的狀態有兩種可能性,他有可能停在c[i]教室,也有可能停在d[i]教室。
可以聯想到 [uva-1336修繕長城] 的那道題,通常為了避免複雜狀態,我們通過加維來解決。所以用f[i][j][0]儲存上次未申請的期望疲勞值,f[i][j][1]表示上次申請的期望疲勞值。但是狀態轉移方程有點讓我糾結。
在dp的時候,就需要乘上事件發生的概率,我一直在糾結的是,發現好像有些情況下只乘乙個概率似乎少了點什麼,糾結了很久,最後問了問旁邊的dalao,果然如此。這是期望dp的套路啊。感覺吃棗藥丸。
那麼由上我想到的思路,就可以很快地得出dp方程,如下。為了讓方程看起來好看一點,我們用cc表示從c[i-1]教室到c[i]教室的路徑,用cd表示c[i-1]教室到d[i]教室的路徑,dc,dd以此類推。
其次,注意到這裡的對f[i-1]的呼叫,每次更新時都只有j,j-1對當前更新的j有影響,那麼我們可以採用滾動陣列的思想,將j倒敘迴圈,這樣得到的方程可以大大降低空間複雜度。
另外,f[i][0][0]是需要特判的,它僅能從f[i-1][0][0]上轉移過來,因此,也有f[
j][0
]+=c
c;f [j
][0]
+=cc
;。需要注意的是,這個更新要在更新完前面的f[
1..j][
0/1]f[
1..j][
0/1]
之後才能更新。
#include
#include
#include
#include
using
namespace
std;
struct dataedge[180010];
const
int inf=0x3f3f3f3f;
int n,m,v,e,p,head[310],c[2010],d[2010],dis[310][310];
double ans=inf,k[2010],f[2010][2];
bool inq[310];
queue
q;template
inline
void read(tp &x)
inline
double fmin(double x,double y)
void input()
}void spfa(int u)}}
}int main()
f[0][0]+=cc;
}for(int j=0;j<=m;j++)
printf("%.2lf\n",ans);
return
0;}
Noip 2016 換教室 期望DP
期望反映了乙個隨機變數的平均結果,是所有可能結果的概率乘上結果的和。例如對於乙個隨機變數x,1 3機率變為1,1 3機率變為2,1 3機率變為3,則x的期望值為 13 1 1 3 2 13 3 21 3 1 13 2 1 3 3 2期望具有線性性質,我們可以根據加法原理和乘法原理來對期望進行計算 可...
NOIP2016 換教室 期望DP
傳送門 題解 本蒟蒻第一次知道期望是啥意思。很簡單,就是全部概率 價值求和 感覺期望差不多都和dp有關吧 設d p i j 0 1 dp i j 0 1 dp i j 0 1 表示選到第i節課,已經申請了換j節課,其中第i節選 不選的期望。dis用floyd處理一下即可。include includ...
noip2016換教室(期望dp
整體思路 這節課換了教室的期望路程 min 上節課換了教室的期望路程 上節課教室到這節課教室的期望路程,上節課沒換教室的期望路程 上節課教室到這節課教室的期望路程 這節課沒換教室的期望路程 min 上節課換了教室的期望路程 上節課教室到這節課教室的期望路程,上節課沒換教室的期望路程 上節課教室到這節...