ZJU2949 Coins of Luck - 数学期望

来源:互联网 发布:linux sh 编辑:程序博客网 时间:2024/04/29 08:43

http://blog.csdn.net/tiaotiaoyly/article/details/2256119


题目描述:

现在有A、B面条各有N碗,用投掷硬币的方式来决定吃哪种面条。当只剩下一种面条时不需要再投掷硬币。输入N,要求将所有面条吃完投掷硬币的数学期望。(N<=1000)

分析:

这个短语一定要认识:mathematical expectation(数学期望)。

回忆求数学期望的一般方法,E=∑ pi×xi。即所有可能的取值×取值的概率然后求和。

我们只考虑把A面条吃完,剩下若干B面条的情况,得出的结果乘以2即可。记组合数c(i,n)为c[n][i];记2的n次幂为pow2[n]。

那么吃完n碗A面条,吃了i碗B面条(0<=i<n)时的概率为:c[n-i-1][i] / pow2[n+i];这种情况下投掷硬币的次数n+i

那么总的期望公式为:E =  2 × ∑( ( c[n-i-1][i] / pow2[n+i] ) × ( n+i ) ) , (0<=i<n)

可以这样理解:总共吃了n+i碗面条,一共要投掷n+i次硬币,所以一共有pow2[n+i]种可能性。而满足吃完n碗A,吃了i碗B的条件,必须最后一碗是吃A面条(因为结束投掷硬币是在A刚好吃完的时候),所以满足条件的情况总数为,前n-1个A和i个B的全排列,也就是n-i-1个位置选i个放置B,其余放置A,共c[n-i-1][i]种情况。

那么期望值为,所有情况的投掷硬币次数×概率之和,再乘以2。

到这里,可以说题目刚刚完成了一半。由于n的范围是1000,组合数c[n][i]和2的n次幂pow2[n]都会很大。是不是需要用大数呢?

分析最后的输出结果只要求保留两位小数,答案也不会超过2000。也就是说,我们尝试用double直接算,只要保证运算过程中不超出范围,最后输出的精度一定是足够的。

查了一下double的取值范围,大约是±1e308,大约是2的1024次方。

单看pow2[n+i],n+i的取值是2000,这就已经超范围了。仔细观察,其实公式可以变形,将pow2[n]提到公式外面:

E = 2 / pow2[n] ) × ∑( ( c[n-i-1][i] / pow2[i] ) × ( n+i ) ) , (0<=i<n)

这样,公式外面和里面的pow2[]数组都在double范围内了。但是尝试了一下用杨辉三角的方式计算c[n][i],到后面的时候还是超了……

和SHP折腾了半天,这里还可以优化一下。观察公式,由于c[x][i]对应的项一定会除以pow2[i],那么就可以在计算c[x][i]的时候边算边除。也许就不会超范围了。

杨辉三角公式,c[n][i] = c[n-1][i] + c[n-1][i-1]。

现在新的c[n][i]保存的是c[n][i] / pow2[i],变形公式:c[n][i] = c[n-1][i] + c[n-1][i-1] / 2。

为什么只在c[n-1][i-1]这项除2?因为按照新的定义方式,c[n-1][i]已经除过pow2[i],c[n-1][i-1]已经除过pow2[i-1],要使c[n][i]的分母是pow2[i],只要在c[n-1][i-1]这一项除2即可。

到这里,题目基本上完美解决了(实际推导过程花了不少时间)……

现在用新定义的c[n][i]来描述最后的公式为:

E = 2 / pow2[n] ) × ∑( c[n-i-1][i] × ( n+i ) ) , (0<=i<n)


0 0
原创粉丝点击