关于骰子的一道算法题(期望、求和、错位相减)
来源:互联网 发布:多媒体显示屏播放软件 编辑:程序博客网 时间:2024/05/18 01:32
海爷和我share了一个很有意思的算法题:
FROM:http://ilewen.com/questions/1534
一个骰子,6面,1个面是 1, 2个面是2, 3个面是3, 问平均掷多少次能使1,2,3都至少出现一次!
首先要知道这个题求什么,最先直接没理解
这题可以翻译为,一个骰子,6面,1个面是 1, 2个面是2, 3个面是3,随机扔骰子,在第x次时3个数都出现,求这个x的期望(也就是扔无数次,x的平均值是多少)
思路:
第一二次肯定不可能出现这种情况
第x(x > 2)次三个都出现的情况分三种(x ^ y 表示 x 的 y 次方)
1:第x次出现 1,那么前面出现的必然是 2 和 3 ,且至少出现一次
出现1的概率为 1 / 6,前面x-1次不出现1的概率为(1 - 1 / 6) ^ (x - 1),
但是其中包含全是 2 和全是 3 的情况,去掉全 2 的概率 (1 / 2) ^ (x - 1),全部为3的概率(1 / 3) ^ (x - 1),
那么情况 1 的概率为 ((1 - 1 / 6) ^ (x - 1) - (1 / 2) ^ (x - 1) - (1 / 3) ^ (x - 1)) * (1 / 6)
2:第x次出现2,那么前面出现的必然是 1 和 3 ,且至少出现一次 同样,概率为 ((1 - 1 / 3) ^ (x - 1) - (1 / 2) ^ (x - 1) - (1 / 6) ^ (x - 1)) * (1 / 3)
3:第x次出现3,那么前面出现的必然是 1 和 2 ,且至少出现一次 同样,概率为 ((1 - 1 / 2) ^ (x - 1) - (1 / 3) ^ (x - 1) - (1 / 6) ^ (x - 1)) * (1 / 2)
p(x)就为上面三种情况的和
那么,根据期望公式,平均值就等于从x = 3 到 n(无穷)求(x * p(x))的和
利用错位相减法计算极限值,附代码
#include "stdio.h" #include "math.h"const int MAX_TRY = 10000;double funBase(double x){ return x * x * (3 + x / (1 - x));}double funOne(double x)//每种情况的极限{ x = 1 - x; return funBase(x) - funBase(1 - x);}double funThree(double x1, double x2, double x3){ return funOne(x1) + funOne(x2) + funOne(x3);//三种情况的极限和}double funTimeBase(double x, int n){ return x * pow((1 - x), n) - (1 - x) * pow(x, n);}double funTimeOne(double x1, double x2, double x3, int n){ return funTimeBase(x1, n) + funTimeBase(x2, n) + funTimeBase(x3, n);}double funTimeAll(double x1, double x2, double x3, int start, int n){//简单的变化 double total = 0; for (int i = start; i < n; ++i) { double look = funTimeOne(x1, x2, x3, i); total += (i + 1)* look; } return total;}double funDirectOne(double x1, double x2, double x3, int n){ double ret = 0; ret += x1 * (pow((1 - x1), n) - pow(x2, n) - pow(x3, n)); ret += x2 * (pow((1 - x2), n) - pow(x1, n) - pow(x3, n)); ret += x3 * (pow((1 - x3), n) - pow(x2, n) - pow(x1, n)); return ret;}double funDirectAll(double x1, double x2, double x3, int start, int n){//按各种情况直接求和 double total = 0; for (int i = start; i < n; ++i) { double look = funDirectOne(x1, x2, x3, i); total += (i + 1) * look; } return total;}int main() { //后面的start = 2表示第三次的概率 double ret = funTimeAll(1.0 / 6, 1.0 / 2, 1.0 / 3, 2, MAX_TRY); printf("%f ", ret); ret = funThree(1.0 / 6, 1.0 / 2, 1.0 / 3); printf("%f ", ret); ret = funDirectAll(1.0 / 6, 1.0 / 2, 1.0 / 3, 2, MAX_TRY); printf("%f\n",ret); return 0;}
先把我的运行结果发出来:
错位相减法是一种常用的数列求和方法,应用于等比数列与等差数列相乘的形式。 形如An=BnCn,其中Bn为等差数列,Cn为等比数列;分别列出Sn,再把所有式子同时乘以等比数列的公比,即kSn;然后错一位,两式相减即可。
如果数列的各项是由一个等差数列和一个等比数列的对应项之积构成的,那么这个数列的前n项和可用此法来求,如等比数列的前n项和公式就是用此法推导的
- 关于骰子的一道算法题(期望、求和、错位相减)
- 扔骰子的一道概率题
- 关于骰子的一个小算法
- 一道关于小鸟的算法题
- 一道关于拆分思路的算法题
- 一道关于排序的算法题
- 一道关于股票买卖的算法编程题
- 一道算法题:求和为某正整数的所有正整数集合
- 骰子作画的算法
- 骰子作画的算法
- 骰子作画的算法
- (lintcode)第20题 骰子求和
- 月初新浪的一道关于算法的笔试题
- 关于骰子游戏的随想
- 一道关于放鸡蛋的算法
- 骰子求和问题
- 3个骰子求和
- LintCode 20 骰子求和
- 进程与线程的一个简单解释
- SDWebImage 笔记
- 计算机基础知识
- 414. The leopard cannot change its spots. 本性难易
- Android应用开发以及设计思想深度剖析(1)
- 关于骰子的一道算法题(期望、求和、错位相减)
- 关于ECSHOP在PHP5.4以上版本中的运行问题.txt
- NYOJ 士兵杀敌(一)
- Android应用开发以及设计思想深度剖析(2)
- oracle数据表被锁
- windows删除svn文件夹
- 《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了
- 控件大小位置随分辨率而变化
- 进程调度