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)
- ZJU2949 Coins of Luck - 数学期望
- ZJU2949 Coins of Luck - 数学期望
- ZOJ 2949 Coins of Luck(概率dp求期望)
- 【概率DP】 ZOJ 2949 Coins of Luck 期望
- zoj 2949 Coins of Luck 抛硬币(概率(期望)+dp)
- zoj 2949 - Coins of Luck
- ZOJ 2949 Coins of Luck 概率DP
- ZOJ 2949 Coins of Luck(概率dp)
- HDOJ 2401 Baskets of Gold Coins(数学,等差数列求和)
- 数学期望
- 数学期望
- 数学期望
- Codeforces 100187B:A Lot of Joy(数学期望)
- eyes of Luck
- 刷一波数学期望,数论,数学
- 条件数学期望
- 一个数学期望问题
- 【数学期望】poj3682
- 《Effective C++ 》学习笔记——条款01
- HDU 1022 Train Problem I 栈的模拟
- [USACO 2014 Feb Silver]scode
- IOS学习---OC基础学习2
- HDU 1237 简单计算器 表达式求值
- ZJU2949 Coins of Luck - 数学期望
- C++回调函数(callback)与仿函数(functor)的异同
- Beautiful String-连续字符串
- 多线程还是多进程的选择及区别
- IOS学习---OC基础学习1
- struts2中文乱码问题的解决方法
- stl-非变异算法
- 【C++】输入流小结
- 给出101个整数数,这101个数是1~100中的数,其中只有一个是出现两次的数,要求找出这个数。