HDU1145 So you want to be a 2n-aire?(随机概率·概率dp·好题)

传送门
题意很简单:问答游戏,初始金额有一块钱,如果选择答的话,答对奖金翻倍,答错就没钱了,如果不答的话就,就维持奖金。答对的概率是 [ t , 1 ] [t,1] [t,1]的一个随机概率。问在最优的策略下, n n n局后能获得的最大奖金期望值。
我们先来简化一下题目。
把概率固定为一个值 p p p
d p [ i ] dp[i] dp[i]为在 n − i n-i ni题后能获得的可能最大奖金。
d p [ n ] = 1 < < n dp[n]=1<dp[n]=1<<n
d p [ 0 ] dp[0] dp[0]即为答案。
b e s t [ i ] best[i] best[i]为答对 i i i题后得到的奖金
b e s t [ i ] = 1 < < i best[i]=1<best[i]=1<<i.
对于某一题,考虑要不要回答,显然如果回答的期望值比不回答的期望值大,则回答,否则不回答。
因为 p p p是确定的,所以要么都回答,要么都不回答。
所以不回答的时候, d p [ i ] = b e x t [ i ] dp[i]=bext[i] dp[i]=bext[i]
回答的时候, d p [ i ] = d p [ i + 1 ] ⋅ p dp[i]=dp[i+1]\cdot p dp[i]=dp[i+1]p
则当 d p [ i + 1 ] ⋅ p > b e x t [ i ] dp[i+1]\cdot p>bext[i] dp[i+1]p>bext[i]时,就选择答题,否则不答题。
回到本题
概率变成了一个范围内的随机,其实看可以分隔无数特定概率。
所以问题的本质就跟上面所说的一样了。
因为 ∫ t 1 p d p 1 − t \frac{\int^{1}_{t}{pdp}}{1-t} 1tt1pdp= 1 + t 2 \frac{1+t}{2} 21+t
所以选择答题的时候,概率的期望值为 1 + t 2 \frac{1+t}{2} 21+t
p = b e s t [ i ] d p [ i + 1 ] p=\frac{best[i]}{dp[i+1]} p=dp[i+1]best[i]
则在 [ t , p ] [t,p] [t,p]内的概率我们选择不回答题,在 [ p , 1 ] [p,1] [p,1]的区间为选择答题,这样得到能得到最大的期望值
显然概率密度为 1 1 − t \frac{1}{1-t} 1t1
所以有 d p [ i ] = [ t > p ] ⋅ p − t 1 − t ⋅ b e s t [ i ] + ( 1 − m a x ( p , t ) ) ⋅ ( 1 + m a x ( p , t ) ) 2 ⋅ ( 1 − t ) d p [ i + 1 ] dp[i]=[t>p] \cdot \frac{p-t}{1-t} \cdot best[i]+\frac{(1-max(p,t))\cdot(1+max(p,t))}{2\cdot(1-t)}dp[i+1] dp[i]=[t>p]1tptbest[i]+2(1t)(1max(p,t))(1+max(p,t))dp[i+1]
代码:

#include
using namespace std;
double dp[40];
double best[40];
int main() {
    best[0]=1;
    for(int i=1;i<=30;i++)best[i]=best[i-1]*2;
    int n;
    double t;
    while(~scanf("%d%lf",&n,&t))
    {
        if(!n&&!t)break;
        dp[n]=best[n];
        for(int i=n-1;i>=0;i--)
        {
            double p=best[i]/dp[i+1];
            dp[i]=(t<p)*(p-t)/(1.0-t)*best[i]+(1.0-max(p,t))/(1-t)*(1.0+max(p,t))/2*dp[i+1];
        }
        printf("%.3f\n",dp[0]);
    }
}

你可能感兴趣的:(dp,数学)