Expect the Expected(dp+概率)

来源:互联网 发布:网络暴力英语ppt 编辑:程序博客网 时间:2024/06/01 09:56

问题:Some mathematical background. This problem asks you to compute the expected value of a random
variable. If you haven’t seen those before, the simple definitions are as follows. A random variable is a
variable that can have one of several values, each with a certain probability. The probabilities of each
possible value are positive and add up to one. The expected value of a random variable is simply the
sum of all its possible values, each multiplied by the corresponding probability. (There are some more
complicated, more general definitions, but you won’t need them now.) For example, the value of a fair,
6-sided die is a random variable that has 6 possible values (from 1 to 6), each with a probability of 1/6.
Its expected value is 1/6 + 2/6 + … + 6/6 = 3.5. Now the problem.
I like to play solitaire. Each time I play a game, I have probability p of solving it and probability
(1 − p) of failing. The game keeps statistics of all my games – what percentage of games I have won.
If I simply keep playing for a long time, this percentage will always hover somewhere around p ∗ 100%.
But I want more.
Here is my plan. Every day, I will play a game of solitaire. If I win, I’ll go to sleep happy until
the next day. If I lose, I’ll keep playing until the fraction of games I have won today becomes larger
than p. At this point, I’ll declare victory and go to sleep. As you can see, at the end of each day, I’m
guaranteed to always keep my statistics above the expected p ∗ 100%. I will have beaten mathematics!
If your intuition is telling you that something here must break, then you are right. I can’t keep
doing this forever because there is a limit on the number of games I can play in one day. Let’s say that
I can play at most n games in one day. How many days can I expect to be able to continue with my
clever plan before it fails? Note that the answer is always at least 1 because it takes me a whole day
of playing to reach a failure.
Input
The first line of input gives the number of cases, N. N test cases follow. Each one is a line containing
p (as a fraction) and n.
1 ≤ N ≤ 3000, 0 ≤ p < 1,
The denominator of p will be at most 1000,
1 ≤ n ≤ 100.
Output
For each test case, print a line of the form ‘Case #x: y’, where y is the expected number of days,
rounded down to the nearest integer. The answer will always be at most 1000 and will never be within
0.001 of a round-off error case.
Sample Input
4
1/2 1
1/2 2
0/1 10
1/2 3
Sample Output
Case #1: 2
Case #2: 2
Case #3: 1
Case #4: 2

百度翻译:一些数学背景。这个问题要求你计算一个随机的期望值
变量。如果你以前没有看到过,简单的定义如下。一个随机变量是
变量,可以有几个值的一个,每个值都有一定的概率。每个概率
可能的值是积极的,并添加到一个。一个随机变量的期望值是简单的
所有可能的值的总和,每一个乘以相应的概率。(有更多的
复杂的,更一般的定义,但你现在不需要它们。)例如,一个公平的,
6模是一个随机变量,有6个可能的值(从1到6),每一个概率为1 / 6。
它的期望值是1 / 6 + 2 / 6 +。..+ 6 / 6 = 3.5。现在的问题。
我喜欢玩纸牌。每次我玩一个游戏,我都有概率p解决它和概率
(1−P)失败。游戏保持了我所有的游戏的统计数字,我赢得了多少游戏的百分比。
如果我只是继续玩很长时间,这一比例一直徘徊在100%∗P。
但我想要更多。
这是我的计划。每一天,我会玩单人纸牌游戏。如果我赢了,我会睡得很开心,直到
第二天。如果我输了,我会继续玩,直到我赢了今天的比赛的分数变大,在这一点上,我会宣布胜利,去睡觉。正如你所看到的,在每一天结束时,我
保证始终保持我的数据比预期∗100% P。我会打败数学!
如果你的直觉告诉你,这里的东西必须打破,那么你是正确的。我不能保持
这样做永远,因为有一个限制,我可以玩游戏的数量在一天。让我们说
我可以在一天最多玩N个游戏。我能指望几天能继续我的
聪明的计划失败之前?请注意,答案总是至少1,因为它花了我一整天
玩到失败。
输入的第一行给出了数量的情况下,N测试用例。每一条都是一条线
P(作为分数)和
1≤N≤3000、0≤P<1,
P的最大值将是最多1000,
1≤N≤100。
对于每一个测试案例,打印一行的形式的情况下# X:Y,其中Y是预期的天数,
四舍五入到最近的整数。答案将永远是在大多数1000,永远不会在
0.001的一个错误的情况下。

思路:这道题可以把自己代入这个主角,假如你每天打牌,如果每次赢钱的概率都是p,然后今天你自己有n次打牌的时间去玩,就是每天能玩n次。然后你每天不赢钱就不舒服,输了就一直打,打到赢钱为止。所以,你打了i次牌中赢了j次,而j/i>=a/b一旦成立,你就可以开心的睡觉了。代码是把每一种情况存在了dp中。我在理解的时候是在草稿本上写了4排,自己写写吧。

AC代码:

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cmath>#include <algorithm>double dp[105][105];using namespace std;int main(){    int N,n,num=1;    char c;    double a,b,p,p2;    cin>>N;    while(N--)    {        p2=0.0;    scanf("%lf%c%lf",&a,&c,&b);    p=(double)a/b;    cin>>n;    memset(dp,0,sizeof(dp));    dp[0][0]=1,dp[0][1]=0;    for(int i=1;i<=n;i++)        for(int j=0;j*b<=i*a;j++)    {        dp[i][j]=dp[i-1][j]*(1-p);        if(j)            dp[i][j]+=dp[i-1][j-1]*p;    }    for(int i=0;i*b<=a*n;i++)    {        p2+=dp[n][i];    }    cout<<"Case #"<<num++<<": "<<int(1/p2)<<endl;    }    return 0;}


1 0
原创粉丝点击