2018.09.23 bzoj1076: [SCOI2008]獎勵關(期望+狀壓dp)
阿新 • • 發佈:2018-12-11
傳送門 一道神奇的期望狀壓dp。 用表示目前在第i輪已選取物品狀態為j,從現在到第k輪能得到的最大貢獻。 如果我們從前向後推有可能會遇到不合法的情況。 所以我們從後向前推。 這時怎麼處理不合法的情況呢? 如果當前這個狀態不具備選擇k的條件。 那麼說明第i+1輪可能具備。 於是 否則當前具備選k的條件。 所以要麼當前輪不選,要麼選了從轉移過來。 程式碼:
#include<bits/stdc++.h>
using namespace std;
double f[105][1<<16];
int K,n,w[16],ban[16];
int main(){
scanf("%d%d",&K,&n);
for(int i=1;i<=n;++i){
scanf("%d",&w[i]);
int tmp;
while(scanf("%d",&tmp)&&tmp)ban[i]|=1<< (tmp-1);
}
int up=1<<n;
for(int i=K;i;--i){
for(int j=0;j<up;++j){
for(int k=1;k<=n;++k){
if((j&ban[k])==ban[k])f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(k-1))]+w[k]);
else f[i][j]+=f[i+1][j];
}
f[i][j]/=1.0*n;
}
}
printf("%.6lf",f[1][0]);
return 0;
}