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]);
}



posted @ 2012-04-09 09:04  Evan1004  阅读(448)  评论(0编辑  收藏  举报