期望dp就要倒着做。。。
dp[i][S],表示前i-1轮过后,目前的宝物获得状态是S,在i~k轮能获得的最大期望。那么答案就是dp[1][0]。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 20
#define ll long long
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int K,n,a[N],bin[N],pre[N];double dp[110][40000];
int main(){
// freopen("a.in","r",stdin);
K=read();n=read();bin[0]=1;
for(int i=1;i<=n;++i) bin[i]=bin[i-1]<<1;
for(int i=0;i<n;++i){
a[i]=read();
while(1){
int x=read();if(!x) break;pre[i]|=bin[x-1];
}
}for(int i=K;i>=1;--i)
for(int S=0;S<=bin[n]-1;++S){
for(int j=0;j<n;++j)
if((S&pre[j])==pre[j]) dp[i][S]+=max(dp[i+1][S],dp[i+1][S|bin[j]]+a[j]);
else dp[i][S]+=dp[i+1][S];
dp[i][S]/=n;
}
printf("%.6lf\n",dp[1][0]);
return 0;
}