【bzoj1076】 SCOI2008—奖励关

http://www.lydsy.com/JudgeOnline/problem.php?id=1076 (题目链接)

题意

  一个奖励,K次抛出宝物的机会,每次抛出都等概率的抛出n个物品中的一个,每个物品有一个价值,想获得每个物品必须先获得一些另一些物品。求最终获得的价值的期望。

Solution

  题意不明啊!!!

  好吧,令${f_{i,s}}$表示第i次,之前获得过的宝物的状态为s的期望得分。

  那么很显然我们可以列出期望方程:

$${f_{i,s}=\sum_{j=1}^{n}Max\{f_{i+1,s|bin[j-1]},f_{i+1,s}\}}$$

  宝物抛出后,可以吃也可以不吃。注意条件。

代码

// bzoj1076
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=110;
int bin[30];
int n,K,S[maxn],p[maxn];
double f[maxn][1<<15];

int main() {
	bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
	scanf("%d%d",&K,&n);
	for (int x,i=1;i<=n;i++) {
		scanf("%d",&p[i]);
		while (scanf("%d",&x)!=EOF && x) S[i]+=bin[x-1];
	}
	for (int i=K;i>=1;i--)
		for (int j=0;j<bin[n];j++) {
			for (int k=1;k<=n;k++) {
				if ((S[k]&j)==S[k]) f[i][j]+=max(f[i+1][j],f[i+1][j|bin[k-1]]+p[k]);   //可以选择不吃
				else f[i][j]+=f[i+1][j];
			}
			f[i][j]/=n;
		}
	printf("%.6lf",f[1][0]);
	return 0;
}

  

posted @ 2016-12-31 19:36  MashiroSky  阅读(641)  评论(0编辑  收藏  举报