[bzoj1076]奖励关

用f[i][j]表示到第i轮,之前取过的状态为j时之后的期望收益,枚举第i轮出现的物品,并判断能否取来转移,最终再将f[i][j]/=n即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,x,a[105],b[105];
 4 double f[105][100005];
 5 int main(){
 6     scanf("%d%d",&m,&n);
 7     for(int i=0;i<n;i++){
 8         scanf("%d",&a[i]);
 9         while (scanf("%d",&x)!=EOF){
10             if (!x)break;
11             b[i]|=(1<<x-1);
12         }
13     }
14     for(int i=m;i;i--)
15         for(int j=0;j<(1<<n);j++){
16             for(int k=0;k<n;k++)
17                 if ((j&b[k])!=b[k])f[i][j]+=f[i+1][j];
18                 else f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<k)]+a[k]);
19             f[i][j]/=n;
20         }
21     printf("%.6f",f[1][0]);
22 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11797631.html