正题
题目大意
kkk轮,每轮抛出随机一个宝物,若一个宝物的前提集合SiS_iSi之前都拿到过,那么就可以拿这个并获得pip_ipi分。
求最大期望分数
解题思路
考虑状态压缩dpdpdp,状态表示宝物是否拿过。
fi,jf_{i,j}fi,j表示第iii轮,宝物状态为jjj时的最大期望价值。
可是我们会发现有时候没有jjj这个状态,我们考虑倒推,因为起始状态只有一个可是终止状态很多。
fi,j=max{fi+1,j,fi+1,j∣(1<<z)+pz(Sz∈j)}f_{i,j}=max\{f_{i+1,j},f_{i+1,j|(1<<z)}+p_z(S_z\in j)\}fi,j=max{fi+1,j,fi+1,j∣(1<<z)+pz(Sz∈j)}
fi,j=fi+1,j+pz(Sz∉j)f_{i,j}=f_{i+1,j}+p_z(S_z\notin j)fi,j=fi+1,j+pz(Sz∈/j)
然后答案就是f1,0f_{1,0}f1,0
codecodecode
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=15;
int k,n,p[N],MS,pre[N];
double maxs,f[110][1<<N];
int main()
{scanf("%d%d",&k,&n);for(int i=0;i<n;i++){int x;scanf("%d%d",&p[i],&x);while(x){x--;pre[i]|=(1<<x);scanf("%d",&x);}}MS=1<<n;for(int i=k;i>=1;i--){for(int j=0;j<MS;j++){for(int z=0;z<n;z++){if((j&pre[z])==pre[z])f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<z)]+p[z]);else f[i][j]+=f[i+1][j];}f[i][j]/=n;}}printf("%lf",f[1][0]);
}