随机生成x个大小为[1,y]的正整数的求解解析
问题:请编写函数foo(int x, int y, int n) 计算:随机生成x个大小为[1,y]的正整数,它们的和为n的概率是多少?
参考代码:
function recursion($x,$y,$n){
if($n<$x || $n>$x*$y){
$tmp[$x][$n] = 0;
}else if($x === 1){
if($y < $n){
$tmp[$x][$n] = 0;
}else{
$tmp[$x][$n] = 1;
}
}
if(isset($tmp[$x][$n])){
return $tmp[$x][$n];
}
$tmp[$x][$n] = 0;
for($i=1; $i<=$y; $i++){
$tmp[$x][$n] += recursion($x-1, $y, $n-$i);
}
return $tmp[$x][$n];
}
function foo($x, $y, $n){
return recursion($x, $y, $n) * 1.0 / pow($y, $x);
}
$sum = 0;
for($i=1;$i<100;$i++){
echo foo(5,10,$i),PHP_EOL;
$sum += foo(5,10,$i);
}
echo 'sum:' . $sum;
看了网上的答案都是直接给代码,表示搞不懂为什么要循环遍历,还要用for循环i从1循环100次。具体希望大神可以从头到脚讲下这个代码的思路。小弟在此十分感谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
那个循环是在计算5个来自[1,10]中随机整数的和等于1的概率,加上等于2的概率,等等这样不断累加,最后加上等于100的概率。因为这样的五个数字的和肯定在5和50之间,所以最后这些概率之和当然是1,从而可以验证
foo
的正确性。你再看他计算
foo
这个概率是用的recursion(x,y,n)/(y^x)
,因此recursion(x,y,n)
是在计算取x
个[1,y]
间的随机整数,它们的和等于n
的方法数。函数名提示我们他是用递归来算的。你要取
x
个这样的数字的方法数是recursion(x,y,n)
,现在按第一个取出的数分类。x-1
个数字的和就必须是n-1
,有recursion(x-1,y,n-1)
种方法。x-1
个数字的和就必须是n-2
,有recursion(x-1,y,n-2)
种方法。等等。也就是说递归公式是:
recursion(x,y,n) = recursion(x-1, y, n-1) + recursion(x-1, y, n-2) + ... + recursion(x-1, y, 0)
这个递归公式如果直接写在代码里比较低效,因为会重复计算。所以他用了
tmp[x][n]
这个表格来缓存中间结果和边界条件(n
不能太大或太小)。通过以上分析再回去看代码,应该就比较清楚了。
//此函数作用递归 $x 到 $y 中的数有那些满足 $x * $y = $n 并放入$tmp 数组中 已 $x 和 $y 作为key区分
function recursion($x,$y,$n){
}
//这里 是算 具体某个 [$x,$y]范围的数到 $n为具体值的概率
function foo($x, $y, $n){
}
$sum = 0;
//最后这里解释下为什么有循环 循环是别人算了 5,10 分别 与 $n = [1 ...100] 所有数的概率
for($i=1;$i<100;$i++){
}
echo 'sum:' . $sum;