bzoj1076: [SCOI2008]奖励关

状态压缩dp。

一道很好的dp题。

我们在选的时候并不知道它会对后面的选择造成什么影响,所以不能正向dp。

f[i][s]表示第i次选择后,选择的宝物二进制为s的期望得分。

初始状态均为0,答案为f[0][0]。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 20;
const int maxm = 1<<16;
const int maxk = 100 + 10;

int n,m,k;
int pre[maxn];
int p[maxn];
double f[maxk][maxm];

int main() {
    scanf("%d%d",&k,&n); m=(1<<n)-1;
    for(int i=1,t;i<=n;i++) {
        scanf("%d",&p[i]);
        while(scanf("%d",&t) && t) 
            pre[i]|=1<<(t-1);
    }
    
    for(int i=k-1;i>=0;i--) {
        for(int s=0;s<=m;s++) {
            for(int j=1;j<=n;j++) 
                if((s&pre[j])==pre[j]) f[i][s]+=max(f[i+1][s],f[i+1][s|(1<<(j-1))]+p[j]);
                else f[i][s]+=f[i+1][s];
            f[i][s]/=n;
        }
    }
    printf("%.6lf\n",f[0][0]);
    return 0;
}
posted @ 2016-06-25 08:59  invoid  阅读(134)  评论(0编辑  收藏  举报