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;
}