概率问题 在炉石传说中,对方英雄满血且对面场上有一个2血精灵龙,我用出一发奥术飞弹,打死精灵龙的概率是多少?

(奥术飞弹是造成3点伤害,随机分配给敌方所有角色,已知精灵龙不会打出负血)这是一期炉石百晓生的问题,答案是50%。我觉得这题不简单,编程得到的结果匪夷所思,接近49.93%但是不到50%.求助大神!!!!!!!!!!!!

C++代码奉上,编程非常渣。

#include<stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
int aa=30;
int bb=2;
void er();
void er()
{
int ll=rand()%2;
if(ll==0)
{
aa=aa-1;
return ;
}

if(ll==1)
{
bb=bb-1;
return ;
}
}
void sandan();
void sandan()
{
if(bb<=0)
{
aa=aa-1;
return ;
}
if(bb>0)
{
er();
return;
}
}
void main()
{
srand(time(NULL));
int ss;
int qq=0,jj=0;
while(jj<10000000)
{
fflush(stdin);
sandan();
sandan();
sandan();
if(bb==0)
{
qq=qq+1;
}
aa=30;
bb=2;
jj=jj+1;
}
printf("在10000000次试验中,精灵龙死了%d次",qq);
}

推荐  (0) | 39人关注关注
33个答案
41 0

饭小盆材料物理学士,飞面神教信徒,FFF团资深团员

2016-02-09 14:52

奥蛋每次攻击都是独立判定的,但是对于这个特定模型来说,只有一种情况下,概率会有不同。。。那就是当前两次伤害已经打死精灵龙,最后一次就只能打脸了。。。

用文字表示的话,打脸是0,精灵龙是1
A000
B001
C010
D011
E100
F101
G110
前面6种都是12.5%的概率出现,最后一种则是25%,那么统计一下出现两次1的情况,就是D、F和G,其中D和F都是12.5%的概率,G是25%,加起来一共50%

如果你采用多次迭代的方法进行统计,那么实际得到的结果跟理论计算确实会有一定的差距。。不妨试试把实验次数提高一些。。。
再附个二叉树的图,省略了根节点

另外给你说个奇怪的事。。。
以前山口山5.4的PTR上进行过一个测试,武器战把精通弄成100%(精通效果是任何攻击都有几率造成一次额外伤害,伤害数值固定,精通本身不会触发精通),那么也就是说,我在一次实验中,其它伤害的攻击次数和触发的精通次数应该是一样的。。。

然而实际结果并不是这样。。。攻击了500多次。。精通触发数量比其他攻击少了几十次。。具体原因未知。。



~~~~~~~~~~~饭盆老师的酸葡萄小课堂~~~~~~~~~~~~~

嘛。。。发现这个问题上了首页并且还有果壳公众号的推送。考虑到题主使用的是代码验证,我决定也写个代码验证一下
由于编辑器娘经常吞掉收尾空格和制表符(其实就是我不会调戏编辑器娘),代码的部分以截图形式放出

一共进行20组实验,每组重复1000000次,结果如下图所示

由此可见前面的推论是正确的

32 0

方弦科学松鼠会成员,信息学硕士生

2016-02-09 14:53

就是50%,除非有什么别的奇怪的分配方法。

做一次实验得到不足或者超过50%都是比较正常的,毕竟有随机性,不会正好是50%

31 0

燃玉理论物理学硕士在读,维基百科小组管理员

2016-02-11 10:47

用Excel算了一下概率:

2血 1血 0血
第1发 50.0% 50.0% 0.0%
第2发 25.0% 50.0% 25.0%
第3发 12.5% 37.5% 50.0%


这东西好像叫马尔科夫链

每行规则是:

2血概率=上回合2血概率*50%

1血概率=上回合2血概率*50%+上回合1血概率*50%

0血概率=上回合1血概率*50%+上回合0血概率


就这样迭代下去

所以N发打死精灵龙的概率也可以算

N发打死M血的概率也可以算

27 0

楼主是试过很多次都是这样吗?
只学过VBS,代码如下

k=0
minion=2
hero=30
for i=0 to 99999
fire()
fire()
fire()
if minion=0 then k=k+1
minion=2
hero=30
next
msgbox "在100000次试验中,精灵龙死了"&k&"次"
function fire()
if minion>0 then
Randomize
if rnd>0.5 then
minion=minion-1
else
hero=hero-1
end if
else
hero=hero-1
end if
end function


试验了100000次,看上去差不多50%

7 0

这答案不是很显然么?

一共3点伤害,2人承担。必须有1人承担不少于2点。在这一点上,即使考虑不能负血的问题,2人仍然是对称的。所以,精灵龙承担的伤害不少于2点就是一半的机会。


6 0

你们啊,一堆答案都没答到要点

楼主其实就是进行了一次蒙特卡洛实验

而monte carlo出来的数字是有一个置信区间的




假设第i次随机实验得到的结果为(根据题意就是精灵龙死了没有)

是一个随机变量,0表示死了,1表示没死,它的分布根据其他楼的计算我们是知道的

p(=0)=0.5

p(=1)=0.5

可以得知的均值是0,5,方差也是0.5

根据大数法则,重复实验n=10000000次之后

死亡次数百分比会服从正态分布,其均值为0.5,但是方差变成

此时我们进行一个假设检验,原假设H0为y=0.5

设置信度为5%,则y有95%的可能性落在一个以0.5为中心的区间

区间的上界可以根据下式算出来

1.96是标准正态分布0.025分位数

下界只要把1.96换成-1.96

最后算出来的区间是[0.49956 , 0.50044]

所以说我们有95%的信心认为精灵龙的死亡百分比会处于以上区间

CyanoHao的答案都处于这个区间内




如果把1.96换成2.58,那么我们就有99%的信心认为y会落在[0.49942,0.50058]之间

而楼主算出来的结果是0.4993

如果不是楼主遇到了小概率事件的话

那么就可以有99%的信心认为原假设是错的,即y不等于0.5,

恭喜楼主,得到了1%水平上的统计显著



当然更有可能的是,楼主程序写错了

比如没有初始化随机seed

7 2

对于我来说,奥术飞弹还是挺听话的,,,,,,,,每次都打脸。。。


4 1

升级版

复仇之怒打死欢笑的姐妹概率是多少

升级版V2.0

死亡丧钟打死鬼灵骑士的概率是多少

1 0
支持者: 哈哈哈哈君i

就是 50% 没有问题。楼主程序模拟的结果不同应该是 VC 随机库的问题。我用 GCC / Glibc 模拟的结果就更接近 50%,大于或小于 50% 都会出现。

0 0

怎么有个最重要的原因没人说。

c语言或者目前所有语言的random函数,都不是真正的随机函数。

因为受限于入力值,只可能得到近似的随机值。

之所以说近似是因为这个得到的随机值,会根据算法的不同呈现周期性的规律。

换句话说,就是根据算法不同,可能会根据时间呈现周期性的规律,或者本身就是一个死循环。

也就是说,哪怕你用c语言的随机函数来预测硬币的正反面,随着取样的样本数量越大,恰好50%的可能性越小。


0 0

我曾经用C++写了个轮盘赌的模拟程序,将一些策略作为输入,可以得到有限局内收益大于本金的结论。结果真的去SkyCity的Casino玩,同样策略还是一样输不少钱。因为游戏规则中玩家的期望就是负的。长期下去玩家不会赢钱。计算机代码永远斗不过概率论与数理统计。数学一定会赢。

rand()产生的是伪随机数,即可以不断产生很长的看似随机的数的序列,但其实并不是真正的随机。如果使用真随机数,就需要使用到随机数发生器。从而生成由纯物理现象产生的随机数。比如来自白噪声等等。鄙人觉得还是按概率论的公式推导比较靠谱,一切使用伪随机数rand()函数的代码都是耍流氓

0 0

0.5 真的不是因为奥蛋的每次伤害单独结算吗?

0 0

这个问题还要编程解决?无论写多少代码,都不能论证你的结论是正确的.

这题用高中的排列组合知识可解.这里我们求三发奥弹击杀不了精灵龙的概率P1,

然后用P2 = 1 - P1即可求得三发奥弹击杀精灵龙的概率.

已知每发奥弹击中精灵龙的概率是0.5, 三发奥弹击杀不了精灵龙的概率分为两种情况:

1. 三发全打脸.概率为 0.5 * 0.5 * 0.5

2. 三发中有两发打脸, 一发打中精灵龙.概率为C(3, 2) * 0.5 * 0.5 * 0.5

所以最后求得P1和P2概率为

P1 = 0.5 * 0.5 * 0.5 + C(3, 2) * 0.5 * 0.5 * 0.5 = 0.125 + 0.375 = 0.5

P2 = 1 - P1 = 0.5

0 0

楼上的各位要来靠数值策划吗?

0 0

玩个游戏没必要这样吧…炉石就是一个看脸和声控的游戏啊

0 0

既然楼主用的是随机算法,那么junglerubik的答案自然最为适合(误差分析及显著性检验)

然而这个问题也并不是像@牛牛跳水 认为的那样无法用变成解决。

在此隆重介绍,动态规划~~~:

#include"stdio.h"
int main()
{
const int DMG=3;//伤害总数
const int HP=2;//精灵龙血量
double F[DMG+1][HP+1];//剩余DMG次伤害还没计算、精灵龙剩余HP点血时的死亡概率
F[0][0]=1;for (int i=1;i<=HP;++i) F[0][i]=0;//设置结束条件
for (int i=1;i<=DMG;++i)//进行DMG次伤害分配
{
F[i][0]=1;//0血即死
for (int j=1;j<=HP;++j)
F[i][j]=F[i-1][j-1]*0.5+F[i-1][j]*0.5;//伤害分配给人和精灵龙的概率是55开
}
printf("%lf\n",F[DMG][HP]);
}

与楼主使用随机算法以频率来逼近概率思路的主要问题是无法得到确切的概率,然而这并不意味着我们不可以直接计算频率。对于这一个问题,我们其实只关心一个概率:进行3次伤害分配杀死2点血的精灵龙的概率是多少,即程序中F[3][2],而对于其他变量,例如玩家血量啊、伤害分配序列啊则不加关心。

而F[3][2],则又可以以类似的方式推导。设当前有DMG个伤害没有结算、精灵龙还有HP点血,这时精灵龙的死亡概率F[DMG][HP]与什么相关呢?自然是打玩家一发和打精灵龙一发后精灵龙的死亡概率。前后两者皆消耗一次伤害结算,不同仅在于精灵龙是否掉血,因此有F[DMG][HP]=0.5*F[DMG-1][HP-1]+0.5*F[DMG-1][HP]。

当然直接利用这个式子的话会出现“子子孙孙无穷尽也”的问题,因此我们要设置一些已知的概率来结束迭代。幸运的是这样的概率很好计算:当DMG=0时,精灵龙HP>0则死亡概率为0%,HP=0则死亡概率为100%,这可以结束DMG减少方向的递归。另外,无论DMG等于多少,HP=0精灵龙定然死翘翘,故

至于楼主特别提到的“精灵龙不能额外承受伤害”这一设定……额,其实你精灵龙都死了,就不用管剩下的伤害该怎么搞了不是么。


动态规划的使用需要满足一定的条件(例如“无后效性”),然而由于这个东西炒鸡直观,因此直接使用基本不会出现问题(当然前提是需要满足逻辑啦)。其实生活中很多问题都可以使用动态规划来求解,是很方便的工具呢。

另外,程序员的“动态规划”和数学的“动态规划”不是一回事……- -|||。如有兴趣,请查阅“背包9讲”

0 0

不就是这么个东西吗…分布概率,高一知识啊

0 0

不会上图, 简单的py代码向楼主靠齐

import random
i=0
n=0
while i<=1000000:
i=i+1
a = random.choice([0,1])
b = random.choice([0,1])

if a==1 and b==1:
c=0
else:
c=random.choice([0,1])

dragon = a+b+c

if dragon==2:
n=n+1

print(n)

多次运行,结果是在500000左右的,也就是概率50%

0 1

我从来没有像楼主这样用C语言来分析游戏,楼主打开了新世界的大门

0 1

既然精灵龙不会被打成负血,那概率怎么会是50%呢?
我用小学生奥数(都不一定是奥数)来说明:
设打到龙为l,打到英雄(人)为r。

龙死:llr lrl rll,三种情况,不存在lll!不存在三发奥蛋都打龙!只有3种!

龙不死有4种:rrr lrr rlr rrl ,打死的概率只有七分之三!

0 3

燕君证券分析师

2016-02-10 22:13

30%~40%之间

这个问题牵扯到一个建模问题,而非单纯的概率

0 3

花痴YY猫花痴 好奇心杀猫的屌丝,学了一点E&E

2016-02-11 02:06

精灵龙不是不能被法术命中吗?

0 4

学习的时候别想游戏,游戏的时候别考虑学习……妈妈说的

0 6

如果我没记错精灵龙是无法成为法术目标的啊

查看更多

添加回答

登录 后回答问题,你也可以用以下帐号直接登录

相关问答

关于我们 加入果壳 媒体报道 帮助中心 果壳活动 家长监控 免责声明 联系我们 移动版 移动应用

©果壳网    京ICP证100430号    京网文[2018] 6282-492号    新出发京零字东150005号     京公网安备11010502007133号

违法和不良信息举报邮箱:jubao@guokr.com    举报电话:18612934101    网上有害信息举报专区    儿童色情信息举报专区