有个技巧,从后往前推,这样方便很多,由于可以取多次,所以状态转移的时候只能用“|”
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
double f[110][1<<15];
int need[110],n,m,k,val[110];
int main()
{
int tmp,a,b;
scanf("%d%d",&k,&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
while(scanf("%d",&tmp)&&tmp)
{
if(tmp==0) break;
need[i]+=(1<<(tmp-1));
}
}
int m=(1<<n)-1;
for(int i=k;i;i--)
{
for(int j=0;j<=m;j++)
{
for(int p=1;p<=n;p++)
{
if((need[p]&j)==need[p])
{
f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(p-1))]+double(val[p]));
}
else
{
f[i][j]+=f[i+1][j];
}
}
f[i][j]/=double(n);
}
}
printf("%.6f",f[1][0]);
return 0;
}