[SCOI 2008] 奖励关

[题目链接]

        https://www.lydsy.com/JudgeOnline/problem.php?id=1076

[算法]

        f[i][S]表示当前第i次抛出宝物,目前集合为S,所能获得的最高分值

        dp即可

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 110
const int MAXS = 1 << 15;

int i,j,k,n,x,s;
int S[MAXN],c[MAXN];
double f[MAXN][MAXS];

inline double dp(int now,int s)
{
    int i;
    if (f[now][s] != -1) return f[now][s];
    if (now == k)    
    {
        f[now][s] = 0;
        for (i = 0; i < n; i++)
        {
            if ((S[i] & s) == S[i] && c[i] > 0)
                f[now][s] += c[i];
        }
        f[now][s] /= n;
    } else
    {
        f[now][s] = 0;
        for (i = 0; i < n; i++)
        {
            if ((S[i] & s) == S[i])
                f[now][s] += max(dp(now + 1,s),dp(now + 1,s | (1 << i)) + c[i]);
            else f[now][s] += dp(now + 1,s);
        }
        f[now][s] /= n;
    }
    return f[now][s];
}

int main()
{
    
    scanf("%d%d",&k,&n);
    for (i = 0; i < n; i++)
    {
        scanf("%d",&c[i]);
        s = 0;
        while (scanf("%d",&x) && x) s |= (1 << (x - 1));
        S[i] = s;
    }
    for (i = 1; i <= k; i++)
    {
        for (j = 0; j < MAXS; j++)
        {
            f[i][j] = -1;
        }
    }
    printf("%.6lf\n",dp(1,0));
    
    return 0;
}

 

posted @ 2018-07-20 17:32  evenbao  阅读(113)  评论(0编辑  收藏  举报