递推,概率DP,概率(你想当2^n元富翁吗?,uva 10900)

http://blog.csdn.net/yeyeyeguoguo/article/details/43503277


其实每个问题都一模一样,答不答只看你现在已拥有多少钱。其实已拥有多少钱是固定的,所以只看概率。


dp[i]就是回答完前i题的期望。

显然能答到第i题,那么前面的题肯定都答对了,因此影响期望的只能是后面的题目了。

所以要从后往前推。

答对的概率是在[t,1]上随机分布的。这就有趣了,因为如果概率是1,那就必答。或者说得更概括一点,就是我们要把答和不答的期望累加起来。

紫书上的递推式可能有些难以看懂。因为那个递推式影藏掉了一些思路上的细节。使得公式更加简洁,不需要讨论,但却难以理解。

下面从头开始一步步分析。

就拿样例来说吧。

1 0.5

1个问题,答对的概率在[0.5,1]上平均分布。

如果不答,就有1块钱。

如果答对了就有2块钱,否则没钱。

这道题我们是一定要答的,因为如果答对的概率是0.5,答不答都一样,而答对的概率如果大于0.5,我们答了的期望一定会更高。

那我们怎么知道该不该答呢?设答对的概率为p,那么如果p*dp[i+1]>2^i,就答吧。或者说p>2^i/dp[i+1],就答。(t<=p<=1)

带入公式就会发现样例一全都应该答。dp[i]=(1+t)/2*dp[i+1]。

但有些时候我们会选择在某些概率下不答,如样例二。

我们发现概率在[0.3,0.5]时不如不答,在[0.5,1]时选择回答。

那么dp[i]=(0.5-0.3)/(1-0.3)*2^i+(1-0.5)/(1-0.3)*dp[i+1]*(1+t)/2。

总结一下就是dp[i]=(p-t)/(1-t)*a[i]+(1-p)/(1-t)*(1+p)/2*dp[i+1];

如果令p=max(t,2^i/dp[i+1]),那么上述两种情况就可合并为第二种情况。避免了讨论。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

double dp[35];
ll a[35];

int main()
{
    a[0]=1;
    for(ll i=1;i<35;i++) a[i]=2*a[i-1];
    ll n;
    double t;
    while(scanf("%lld %lf",&n,&t)==2&&(n+t))
    {
        dp[n]=a[n];
        for(ll i=n-1;i>=0;i--)
        {
            double p=max(t,a[i]/dp[i+1]);
            dp[i]=(p-t)/(1-t)*a[i]+(1-p)/(1-t)*(1+p)/2*dp[i+1];
        }
        printf("%.3lf\n",dp[0]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值