BZOJ1076 [SCOI2008] 奖励关

题目大意:从后往前推,每次操作要枚举每种宝物,分取和不取2种情况,状态要用二进制存。正推不太好判断...于是倒推,意义就变成了:要想取得某个物品,先需要支付当前物品的代价,这样DP就没问题了。

附代码:

View Code
/**************************************************************

    Problem: 1076

    User: 1012haoyifan

    Language: C++

    Result: Accepted

    Time:1156 ms

    Memory:53496 kb

****************************************************************/

 

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<iostream>

#include<algorithm>

#define P(i) (1<<(i-1))

using namespace std;

double f[102][65536];

int N,K,t;

int v[20];

int d[20];

int main()

{

    //freopen("in","r",stdin);

    scanf("%d%d",&N,&K);

    for (int i=1;i<=K;i++)

    {

        scanf("%d",&v[i]);

        scanf("%d",&t);

        while (t)

        {

            d[i]+=P(t);

            scanf("%d",&t);

            }

        }

    for (int i=N;i;i--)

        for (int j=0;j<=P(K+1)-1;j++)

        {

            f[i][j]=0;

            for (int k=1;k<=K;k++)

                if ((d[k]&j)==d[k])

                    f[i][j]+=max(f[i+1][j],f[i+1][j|P(k)]+v[k]);

                else

                    f[i][j]+=f[i+1][j];

            f[i][j]/=(double)K;

        }

    printf("%.6lf\n",f[1][0]);

}



你可能感兴趣的:(2008)