题目描述
小 G 进入了一个神奇的世界,在这个世界,天上会掉下一些馅饼。今天,天上
会随机掉下 k 个馅饼。
每次天上掉下馅饼,小 G 可以选择吃或者不吃(必须在下一个馅饼掉下来之前
作出选择,并且现在决定不吃的话以后也不能吃)。
馅饼有 n 种不同的馅,根据物理定律,天上掉下这 n 种馅饼的概率相同且相互
独立。然而,每一种馅饼 i 都有一个前提馅饼集合 Si。只有当 Si 中的馅饼都吃过
之后,才能吃第 i 种馅饼。比如说,韭菜馅馅饼的 S 中有白菜猪肉馅饼和鲜虾馅饼,
那么小 G 只有在吃过白菜猪肉馅饼和鲜虾馅饼之后,才能吃韭菜馅的馅饼。
同时,每个馅饼还有一个美味值 Pi。今天一天小 G 的幸福度,等于小 G 吃到
的所有馅饼的美味值之和。注意,Pi 可能是负数。
现在考虑,在采用最优策略的前提下,小 G 这一天期望的幸福度是多少?
输入格式
第一行两个正整数 k 和 n,表示馅饼的数量和种类。
以下 n 行,每行若干个数,描述一种馅饼。其中第一个数代表美味值,随后的
整数表示该馅饼的前提馅饼,以 0 结尾。
输出格式
输出一个实数,保留 6 位小数,即在最优策略下期望的幸福度。
样例输入 1
1 2
1 0
2 0
样例输出 1
1.500000
数据范围
对于 20% 的数据,所有的馅饼都没有“前提馅饼”
对于 50% 的数据,1 ≤ k ≤ 10,1 ≤ n ≤ 10
对于 100% 的数据,1 ≤ k ≤ 100,1 ≤ n ≤ 15,美味度为属于 [-10^6; 10^6] 的整数
分析:显然是一道状压dp的题,设f[i][j]为掉落的前i个馅饼中,吃了状态为j的幸福度,当前馅饼i能不能吃取决于状态j是不是i的前提馅饼集合的子集.但是这样并不好维护,我们不知道状态j是否合法.对于这类前面状态约束后面的转移,我们要采用倒着递推的方式来处理.

f[i][j] = max(f[i + 1][j | (1 << (l - 1))] + p[l],f[i + 1][j]).其中l为当前吃的馅饼种类,p为馅饼的幸福度.这样我们从一个已知的合法状态转移到了前面的合法状态.

但是题目要求期望值怎么办呢?期望值实际上就是加权平均值,算一下每一次吃馅饼每一种馅饼掉落的概率,对于第一次吃馅饼,每一种馅饼掉落的概率是1/n,第二次吃馅饼,概率是(1/n) ^ 2,以此类推,所以在转移的时候f[i][j] /= n就可以了.

前面状态约束后面的转移,我们要采用倒着递推的方式来处理!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int k, n, p[], stu[( << ) + ];
double f[][( << ) + ]; int main()
{
scanf("%d%d", &k, &n);
for (int i = ; i <= n; i++)
{
scanf("%d", &p[i]);
int x;
while (scanf("%d", &x) && x != )
stu[i] |= ( << (x - ));
}
for (int i = k; i >= ; i--)
for (int j = ; j < ( << n); j++)
{
for (int l = ; l <= n; l++)
if ((stu[l] & j) == stu[l])
f[i][j] += max(f[i + ][j], f[i + ][j | ( << (l - ))] + p[l]);
else
f[i][j] += f[i + ][j];
f[i][j] /= n;
}
printf("%.6lf\n", f[][]); return ;
}

最新文章

  1. Mongodb基本数据类型、常用命令之增加、更新、删除
  2. LeetCode:Subsets I II
  3. 浅谈如何使用python抓取网页中的动态数据
  4. Redis内存缓存系统入门
  5. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
  6. android SFC
  7. json格式的字符串使用string.Format()方法报错:输入字符串的格式不正确
  8. 超强vim配置文件
  9. java基础之抽象类与接口的区别
  10. Leetcode OJ 刷题
  11. 上传文件块client实现
  12. 使用vue+iview实现上传文件及常用的下载文件的方法
  13. 20175329 2018-2019-3《Java程序设计》第五周学习总结
  14. AssetManager
  15. Python2.6 升级2.7
  16. ajax添加header信息
  17. USB-HID鼠标、键盘通讯格式【转】
  18. hadoop完全分布式搭建HA(高可用)
  19. eagle学习汇总
  20. 2017-2018-2 『Java程序设计』课程 结对编程练习_四则运算

热门文章

  1. POJ 3264 Balanced Lineup 区间最值
  2. 洛谷 P3806 点分治模板
  3. poj1988Cute Stacking
  4. Java高质量20问
  5. dialog的各类显示方法
  6. 点击文字弹出一个DIV层窗口代码 【或FORM表单 并且获取点击按钮的ID值】
  7. 349 Intersection of Two Arrays 两个数组的交集
  8. Flume特点
  9. [Codeforces]Codeforces Round #489 (Div. 2)
  10. 黑马程序员 关于c# windows窗体关闭时线程未能完全退出问题(专题一)