UVa 10900 - So you want to be a 2n-aire?(期望DP)

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1841

 

题意:

在一个电视娱乐节目中,你一开始有1元钱。主持人会问你n个问题,每次你听到问题后有两个选择:
一是放弃回答该问题,退出游戏,拿走奖金;二是回答问题。
如果回答正确,奖金加倍;如果回答错误,游戏结束,你一分钱也拿不到。
如果正确地回答完所有n个问题,你将拿走所有的2^n元钱,成为2^n元富翁。
当然,回答问题是有风险的。每次听到问题后,你可以立刻估计出答对的概率。
由于主持人会随机问问题,你可以认为每个问题的答对概率在t和1之间均匀分布。
输入整数n和实数t(1≤n≤30,0≤t≤1),你的任务是求出在最优策略下,拿走的奖金金额的期望值。
这里的最优策略是指让奖金的期望值尽量大。

 

分析:

假设刚开始游戏,如果直接放弃,奖金为1;如果回答,期望奖金为(p * 答对1题后的最大期望奖金)。
用d[i]表示“答对i题后的最大期望奖金”,再加上“不回答”时的情况,可以得到:
若第1题答对概率为p,期望奖金的最大值 = max{2^0, p*d[1]},
这里故意写成2^0,强调这是“答对0题后放弃”所得到的最终奖金。
上述分析可以推广到一般情况,但是要注意一点:到目前为止,一直假定p是已知的,
而p实际上并不固定,而是在t~1内均匀分布。可以得到:d[i] = max{2^i, p*d[i+1]}。
因为有max函数的存在,需要分两种情况讨论,即p*d[i+1]<2^i和p*d[i+1]≥2^i两种情况。
令p0=max{t, 2^i/d[i+1]}(加了一个max是因为根据题目,p≥t),则:
p<p0时,p*d[i+1]<2^i,因此“不回答”比较好,期望奖金等于2^i。
p≥p0时,“回答”比较好,期望奖金等于d[i+1]乘以p的平均值,即(1+p0)/2 * d[i+1]。
在第一种情况中,p的实际范围是[t,p0),因此概率为p1=(p0-t)/(1-t)。
根据全期望公式,d[i] = 2^i * p1 + (1+p0)/2 * d[i+1] * (1-p1)。
边界是d[n] = 2^n,逆向递推出d[0]就是本题的答案。

 

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int UP = 30 + 5;
 6 double d[UP];
 7 
 8 int main() {
 9     int n;
10     double t;
11     while(scanf("%d%lf", &n, &t) && n) {
12         d[n] = 1<<n;
13         for(int i = n-1; i >= 0; i--) {
14             double p0 = max(t, (double)(1<<i) / d[i+1]);
15             double p1 = (p0-t) / (1-t);
16             d[i] = p1 * (1<<i) + (1-p1) * (1+p0)/2 * d[i+1];
17         }
18         printf("%.3f\n", d[0]);
19     }
20     return 0;
21 }

 

posted @ 2018-09-04 20:30  Ctfes  阅读(183)  评论(0编辑  收藏  举报