So you want to be a 2n-aire?

描述

游戏者开始是$1的奖金,要求回答n个问题。对每个问题,可以:
1)、退出并保有奖金
2)、回答问题。
如果错误,就退出并什么都得不到。如果正确,那么奖金翻倍,并可继续回答下一个问题。
在回答最后一个问题后,他获得奖金并退出。游戏者想要最大化他期望获得的奖金。
一旦提出了一个问题,游戏者就能以概率p正确回答。对每个问题,假设p是一个随机变量,分布的范围是t<=p<=1。

输入

输入M行数,每一行有两个数字:整数n和实数t, 1 ≤ n ≤ 30, 0 ≤ t ≤ 1。n表示要回答的问题的个数,t表示游戏者能正确回答问题的概率的下限。以两个0表示输入结束。

输出

对每个输入n,t,输出游戏者采用最佳策略时所期望获得的奖金,保留三位小数。

样例输入

1 0.5
1 0.3
2 0.6
0 0

样例输出

1.500
1.357
2.560

这个题目从一开始思路上就有问题,后来结合别人的解题报告来看,终于明白是怎么回事了,而且也突然发现,貌似我适合冒险但不适合赌博……

    我们不妨设a[i]表示正确做完第i道题的收益的期望,显然我们最后要求的就是a[0]咯,但这个先放一放,我们先讨论一下在做第i+1个题目前我们是选择答题呢还是选择放弃呢。

    首先,我们可以直观的想到,如果做完i题就退出的话,就可以得到2^i这么多钱。不妨假设答对第i+1个题的概率为p,那么我们自然会想到用p乘以“某个值”表示答题所获得的收益的期望,如果p乘以这个值大于2^i的话,我们肯定会选择答题咯,因为若是这样答题的话收益的期望是大于不答题的。那么现在问题就来了,这个“某个值”是什么呢?可能的最大值?可能的最小值?还是平均值(或者说是期望)?

    如果做个比喻的话,选最大值的就是冒险狂,选最小值的就是胆小鬼,选平均值的就是接受过良好高等教育的ACMer,一开始我就成了冒险狂……

    后来想想,也确实只有平均值在统计里面才比较有说服力,因此题目中所谓的plays the best strategy就是按我们上面所说的去决策每次究竟是答题还是不答题。上面我们只是对于p是固定值来讨论的,如果我们对p是任意的去讨论的话,显然不答题的平均收益是不变的,因为它和p没关系,仍是2^i,如果答题的话平均收益就应该是(ep+1)/2*a[i+1],ep就是我们前面讨论的“分水岭”,用表达式写出来就是ep=2^i/a[i+1],当p>ep,那么p*a[i+1]>2^i,也就是说如果答对这个题我就可以获得a[i+1]这么多钱,再乘答对的概率p就是答第i+1题的收益的期望,如果这个期望大于2^i,那么就会选择答题。当然题目中让算的是总收益,我们再各自乘以答题与否这些情况出现的概率即可,即a[i]=(ep-t)/(1-t)*2^i+(t-ep)/(1-t)*(ep+1)/2*a[i+1],这个式子值列出了ep>t的情况,对于ep<=t的情况,也可以类似写出表达式。

    现在我们就发现了,计算a[i]是需要用到a[i+1]的,那我们怎么办?倒着算呗。那么a[N]是多少?显然是2^N,因为答对第N个题之后收益的期望自然就是最大的收益。

 

#include<stdio.h>
#include<string.h>
#include<math.h>
#define MX 35
int N;
double T, q[MX];
int main()
{
    q[0] = 1;
    for(int i = 1; i <= 30; i ++)
         q[i] = 2 * q[i - 1];
    while(1)
    {
          scanf("%d%lf", &N, &T);
           if(!N)
                 break;
            if(fabs(1 - T) < 1e-9)
                printf("%.3lf\n", q[N]);
          else
          {
                int i, j, k;
                double eq, f = 1, quit;
                f = q[N];
                for(i = N - 1; i >= 0; i --)
                 {
                     quit = q[i];
                     eq = quit / f;
                    if(eq <= T)
                    f = (T + 1) / 2 * f;
               else
                       f = (eq - T) / (1 - T) * quit + (1 - eq) / (1 - T) * (eq + 1) / 2 * f;
    }
    printf("%.3lf\n", f);
          }
    }
    return 0;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值