[bzoj1076]奖励关
f[i][S]:i~n中选了集合S的期望
f[i][j]+=max(f[i+1][j|(1<<(k-1))]+a[k],f[i+1][j])/n (如果j可以转移到j|(1<<(k-1)))
f[i][j]+=f[i+1][j]/n (其他情况)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdlib> 5 #include <map> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <cmath> 10 #include <queue> 11 #include <cstdio> 12 using namespace std; 13 14 int k,n,a[200],p[200]; 15 double f[200][1<<16]; 16 int main(){ 17 scanf("%d%d",&k,&n); 18 for(int i=1;i<=n;i++){ 19 scanf("%d",&a[i]); 20 int S=0,x; 21 while(scanf("%d",&x)==1&&x)S|=1<<(x-1); 22 p[i]=S; 23 } 24 for(int i=k;i>=1;i--){ 25 for(int j=0;j<(1<<n);j++){ 26 for(int k=1;k<=n;k++){ 27 if((j&p[k])==p[k]) 28 f[i][j]+=max(f[i+1][j|(1<<(k-1))]+a[k],f[i+1][j])/n; 29 else 30 f[i][j]+=f[i+1][j]/n; 31 } 32 } 33 } 34 printf("%.6f\n",f[1][0]); 35 }