1. 程式人生 > >洛谷P2473 [SCOI2008]獎勵關(期望+狀壓)

洛谷P2473 [SCOI2008]獎勵關(期望+狀壓)

har targe 期望 num include 不一定 stdin print 一個

傳送門

我數學期望還是太差了……

先考慮狀壓模型,設$dp[i][S]$表示第$i$輪,當前寶物狀態為$S$,能獲得的最大期望分數

然而這個模型有一個問題,第$i$輪不一定能達到狀態$S$

那麽考慮轉化一下,$dp[i][S]$表示第$1$至$i-1$輪的寶物狀態為$S$,第$i$至$n$輪的期望分數

那麽我們就可以倒推了

那麽對於第$k$個寶物,可以分為兩種情況

1.可以選,那麽此時可以選擇選或者不選,則$dp[i][S]+=max\{dp[i+1][S],dp[i+1][S|(1<<k-1)]+a[k]\}$

2.不能選,那麽$dp[i][S]+=dp[i+1][S]$

然後因為這玩意兒是一個期望,所以每一次做完之後都得$dp[i][S]/=n$

 1 //minamoto
 2 #include<cstdio>
 3 #define max(a,b) ((a)>(b)?(a):(b))
 4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 5 char buf[1<<21],*p1=buf,*p2=buf;
 6 inline int read(){
 7     #define
num ch-‘0‘ 8 char ch;bool flag=0;int res; 9 while((ch=getc())>9||ch<0) 10 (ch==-)&&(flag=true); 11 for(res=num;(ch=getc())<=9&&ch>=0;res=res*10+num); 12 (flag)&&(res=-res); 13 #undef num 14 return res; 15 } 16 const int N=105
; 17 int n,m,sta[17],a[17],S;double dp[N][1<<15]; 18 int main(){ 19 // freopen("testdata.in","r",stdin); 20 m=read(),n=read(),S=1<<n; 21 for(int i=1,x;i<=n;++i){ 22 a[i]=read(); 23 while(x=read()) sta[i]|=1<<x-1; 24 } 25 for(int i=m;i;--i) 26 for(int j=0;j<S;++j){ 27 for(int k=1;k<=n;++k){ 28 if((j&sta[k])==sta[k]) dp[i][j]+=max(dp[i+1][j],dp[i+1][j|(1<<k-1)]+a[k]); 29 else dp[i][j]+=dp[i+1][j]; 30 } 31 dp[i][j]/=n; 32 } 33 printf("%.6lf\n",dp[1][0]); 34 return 0; 35 }

洛谷P2473 [SCOI2008]獎勵關(期望+狀壓)