题解:

状压dp+概率

f[i][j]表示正在扔第i次,已经有了j这些物品(状压),还可以拿多少价值

考虑当前抛第k个物品

当k的要求满足,f[i][j]+=1/n*max(f[i+1][j']+a[i],f[i+1][j])

当不满足,f[i][j]+=1/n*f[i+1][j]

其中j'=j|(1<<(k))(我是从0开始标号的)

代码:

#include<bits/stdc++.h>
using namespace std;
int p[105][1<<17],n,m,b[105];
double f[105][1<<16],a[105],P;
double dfs(int x,int y)
{
    if (x>m)return 0;
    if (p[x][y])return f[x][y];
    p[x][y]=1;
    for (int i=0;i<n;i++)
     {         
         if ((y&b[i])!=b[i])f[x][y]+=(P*dfs(x+1,y));
         else f[x][y]+=max(P*dfs(x+1,y),P*(dfs(x+1,y|(1<<i))+a[i]));
     }
    return f[x][y];
}
int main()
{
    scanf("%d%d",&m,&n);
    P=1;
    P/=n;
    for (int i=0;i<n;i++)
     {
         scanf("%lf",&a[i]);
         int x;
         scanf("%d",&x);
         while (x)
          {
              b[i]+=(1<<(x-1));
              scanf("%d",&x);
          }
     }
    printf("%.6lf",dfs(1,0));
}

 

posted on 2017-10-05 09:50  宣毅鸣  阅读(122)  评论(0编辑  收藏  举报