终于又一次迎来了一道期望DP题,按照约定,小C把它贴了出来。

Description

  你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关。在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃)。 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立。也就是说,即使前k-1次系统都抛出宝物1(这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n。 获取第i种宝物将得到Pi分,但并不是每种宝物都是可以随意获取的。第i种宝物有一个前提宝物集合Si。只有当Si中所有宝物都至少吃过一次,才能吃第i种宝物(如果系统抛出了一个目前不能吃的宝物,相当于白白的损失了一次机会)。注意,Pi可以是负数,但如果它是很多高分宝物的前提,损失短期利益而吃掉这个负分宝物将获得更大的长期利益。 假设你采取最优策略,平均情况你一共能在奖励关得到多少分值?

Input

  第一行为两个正整数k和n,即宝物的数量和种类。以下n行分别描述一种宝物,其中第一个整数代表分值,随后的整数依次代表该宝物的各个前提宝物(各宝物编号为1到n),以0结尾。

Output

  输出一个实数,保留六位小数,即在最优策略下平均情况的得分。

Sample Input

  1 2
  1 0
  2 0

Sample Output

  1.500000

HINT

  1<=k<=100,1<=n<=15,分值为[-10^6,10^6]内的整数。

Solution

  关于概率期望的题目让人头大,但是如果你还记得之前的口诀“概率正着做,期望倒着做”,这题就会变得很无脑。

  很显然这题要我们求的是期望,所以我们倒着开始思考问题。

  我们注意到n的范围小等于15,那还能是什么做法啊,当然是状压啊。

  于是我们考虑设计状态,f[i][j]表示取了已经抛出i次物品,并且取了集合为j的物品至少1次,这之后按照最优策略能取到的期望值。

  所谓最优策略,实际上就是比较转移代价和目标收益之间的大小关系,

  假设我们在状态f[i][j],假设可以取得物品x,我们就要斟酌一下取得x的代价和取得x之后的收益,

  也就是比较-w[x]和f[i+1][j|ys[x]]的大小,

  如果-w[x]<f[i+1][j|ys[x]],也就是说收益更大,按照最优原则我们应该要取;(为什么是“应该”呢)

  反之就是代价更大,按照最优原则我们肯定不能取,但是请注意,不取x也有一个收益,那就是f[i+1][j]。

  不过就算取x的收益比代价大,但这两者的差值不一定大于不取x的收益,所以按照最优策略还是要对两者取一个max。

  结合上面的思路来看,我们发现f[i][j]永远不可能是负数。

  前面说的是能够取得物品x的情况,那么什么时候取不了物品x(未满足x的前提宝物集合)呢?

  这种问题还用问?看看你自己设计的状态就知道了吧。

  转移方程:

  其中如果取不了物品k,用 0 代替。

  时间复杂度,虽然复杂度有5亿然而却跑得飞快。

#include <cstdio>
#include <algorithm>
#include <cstring>
#define MS 17
#define MN 35005
using namespace std;
int ys[MS],w[MS],prt[MS];
double f[][MN];
int m,n,stp; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} int main()
{
register int i,j,k,x,lg,rg;
m=read(); n=read();
for (ys[]=,i=;i<=n;++i) ys[i]=ys[i-]<<;
stp=ys[n]<<;
for (i=;i<=n;++i)
for (w[i]=read(),x=read();x;x=read()) prt[i]|=ys[x];
for (i=m-,lg=,rg=;i>=;--i,swap(lg,rg))
for (j=;j<stp;f[lg][j++]/=n)
for (f[lg][j]=,k=;k<=n;++k)
f[lg][j]+=max(((j&prt[k])==prt[k])?f[rg][j|ys[k]]+w[k]:,f[rg][j]);
printf("%.6lf",f[rg][]);
}

Last Word

  自己手算一些小数据也是不错的调试技巧。

  为了缩行可能代码画风会有点崩坏。

[BZOJ]1076 奖励关(SCOI2008)的更多相关文章

  1. BZOJ 1076 奖励关 状态压缩DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1076 题目大意: 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里, ...

  2. scoi 2008 && bzoj 1076 奖励关

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 思路:15?好,状压,OK. 这是转移方程 if((s[k]&j)==s[k] ...

  3. BZOJ 1076 奖励关

    注意几点: 1.为什么要逆推?由此状态可以轻易算出彼状态是否可行,而彼状态却无法轻易还原为此状态. 2.为什么可以逆推?假设时光倒流了....23333 3.注意位运算的准确,大胆写方程. #incl ...

  4. bzoj 1076 奖励关 状压+期望dp

    因为每次选择都是有后效性的,直接dp肯定不行,所以需要逆推. f[i][j]表示从第i次开始,初始状态为j的期望收益 #include<cstdio> #include<cstrin ...

  5. BZOJ 1076 奖励关(状压期望DP)

    当前得分期望=(上一轮得分期望+这一轮得分)/m dp[i,j]:第i轮拿的物品方案为j的最优得分期望 如果我们正着去做,会出现从不合法状态(比如前i个根本无法达到j这种方案),所以从后向前推 如果当 ...

  6. 【bzoj 1076】【SCOI2008】奖励关

    1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1602  Solved: 891[Submit][Status ...

  7. 【BZOJ】【1076】【SCOI2008】奖励关

    状压DP+数学期望 蒟蒻不会啊……看题跑…… Orz了一下Hzwer,发现自己现在真是太水了,难道不看题解就一道题也不会捉了吗? 题目数据范围不大……100*(2^16)很容易就跑过去了…… DP的时 ...

  8. 【BZOJ】1076: [SCOI2008]奖励关(状压dp+数学期望)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1076 有时候人蠢还真是蠢.一开始我看不懂期望啊..白书上其实讲得很详细的,什么全概率,全期望(这个压 ...

  9. bzoj 1076: [SCOI2008]奖励关

    Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝 ...

随机推荐

  1. PostgreSQL 配置安装

    Mac 安装 http://postgresapp.com/ 创建和删除数据库用户 对应命令如下(在postgres=# 环境下):1.查看数据库用户列表: \du2.创建数据库用户: create ...

  2. OpenShift实战(一):OpenShift高级安装

    1.1 服务器基本信息 本次安装采用一个master.5个node.3个etcd,node节点两块硬盘,60G磁盘用于docker storage,xxx改为自己的域名或主机名. 节点 功能 IP 内 ...

  3. slf4j 与 log4j2 实战讲解与日志分割

    这两天搭建项目的时候用到log4j2在这里把自己的问题与了解拿出来与大家分享一下. 1.为什我要用 因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用l ...

  4. JAVA_SE基础——46.引用数据类型变量.值交换[独家深入解析]

    需求:定义一个函数交换数组中两个元素的位置. code 1: import java.util.*; class Demo3 { public static void main(String[] ar ...

  5. xxe漏洞检测及代码执行过程

    这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目録遍历等.首先存在漏洞的web服务一定是存 ...

  6. pythoncharm 中解决启动server时出现 “django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured”的错误

    背景介绍 最近,尝试着用pythoncharm 这个All-star IDE来搞一搞Django,于是乎,下载专业版,PJ等等一系列操作之后,终于得偿所愿.可以开工了. 错误 在园子里找了一篇初学者的 ...

  7. php的api及登录的权限验证

    类,库,接口(APi),函数,这些概念都是根据问题规模的大小来界定的.一个很小的问题肯定没有必要写成一个库,只需要写几句话就行了. 但是比如一个登录验证,这个功能很强大,很通用,可能前台后台都需要用到 ...

  8. Gson序列化对象如何忽略字段

    Gson序列化对象如何忽略字段 Gson版本 2.8.2 梗概 用注解@Expose(serialize = false, deserialize = false)在类的成员上以告诉Gson 跳过本字 ...

  9. Column Addition~DP(脑子抽了,当时没有想到)

    Description A multi-digit column addition is a formula on adding two integers written like this:

  10. Python-面向对象(二)-Day7

    1.字段 12.方法 43.属性 63.1.属性的基本使用 73.2.实例:对于主机列表 83.3.属性的两种定义方式 94.对于类的成员而言都有两种形式: 144.1.私有成员和公有成员的访问限制不 ...