[编程题]骰子期望 Golang

[编程题]骰子期望
这套卷子做下来感觉很难受,每道题都有思路,但是只有第一道题完美通过,做题速度堪忧。
本想把5道题都做了整一套题解,但是明天有华为笔试,我得去刷华为面经了,先写两道吧,剩下的后面再更新。

还是结合例子来讲。
4颗,
最大值:25 9 10 43。

因为每颗骰子的结果都是独立的,同时每一面出现的可能都是相同的,因此可以用可能性相除得概率。

总的可能性为 25 × 9 × 10 × 43 25\times9\times10\times43 25×9×10×43种。

最大值为k(例如k=5)的可能性怎么求呢?
我们先求所有骰子值 x ≤ k x{\le}k xk的情况: 5 × 5 × 5 × 5 5\times5\times5\times5 5×5×5×5
然后再求所有骰子值 x ≤ k − 1 x{\le}k-1 xk1的情况: 4 × 4 × 4 × 4 4\times4\times4\times4 4×4×4×4
(如果k大于某一个骰子的最大值x,乘数取x。)

那么我们将前者减去后者,就可以得到:
所有骰子值 x ≤ k x{\le}k xk并且不全部 ≤ k − 1 {\le}k-1 k1的情况,
换句话说必定存在 x = k x=k x=k
实际上得到的就是最大值为k的所有可能性。

将一类可能性除以总的可能性得概率,概率乘数值再求和得期望。

还有一个细节值得一提,我最开始的做法是
将每一类可能性 乘以 其最大值 求和之后 再除以 总的可能性。
这样会溢出。

所以不能等到最后再除,求和的过程中顺便除一下就不会溢出了。

package main

import "fmt"

func min(a,b int) int {
	if a<b{
		return a
	}else {
		return b
	}
}

func main() {
	var n,num int
	total:=1
	max:=0
	//fmt.Println(min)
	var nums []int
	fmt.Scan(&n)
	for i:=0;i<n;i++{
		fmt.Scan(&num)
		if num>max{
			max=num
		}
		total*=num
		nums= append(nums,num )
	}
	var ans float64
	pre:=0.0
	for i:=1;i<=max;i++{
		cur:=1.0
		for j:=0;j<n;j++{
			cur*=float64(min(i,nums[j]))/float64(nums[j])
		}
		ans+=(cur-pre)*float64(i)
		pre=cur
	}
	fmt.Printf("%.2f",ans)
}

你可能感兴趣的:(算法,go,面试,算法)