#
#背景
最近玩的某游戏开了新卡池,抽了8个10连共计80次,
出了4个稀有度最高的角色,
我突发奇想想算算我这个爆率算什么水平,
程序模拟一下,顺便复习排列组合。
#程序设计
Java 标准类库中,没有排列组合甚至阶乘的现成方法, 搜了一下
但为了这个引入一个第三方库又未免太麻烦,于是自己来实现。
实现第一想到的是 int 和 long 两个基本类型,但想了想发现有坑 :int 最多12!,long 最多到20!
这可不行,我这都80抽了。
于是换 Java 的 BigDecimal 类(大整数)。
问题换算成伪代码是这样:
res=0
res += c(n, i) * 爆率^i * (1 - a)^(n-i) (i=a~b,i为整数)
#代码
import java.math.BigDecimal;
public class factorial {
public static void main(String[] args) {
// 出货率2.5%
double a = 0.025d;
int n = 80;
// result
double res = 0;
double res2 = 0;
for (int i = 0; i < 5; i++) {
res2 += c(n, i).longValue() * Math.pow(a, i) * Math.pow(1 - a, n - i);
}
System.out.println("0~4: " + res2);
for (int i = 4; i < n + 1; i++) {
res += c(n, i).longValue() * Math.pow(a, i) * Math.pow(1 - a, n - i);
}
System.out.println("4~80: " + res);
}
// n!
public static BigDecimal n(int n) {
if (n == 0)
return new BigDecimal(0);
BigDecimal result = new BigDecimal(1);
BigDecimal a;
for (int i = 2; i < n + 1; i++) {
a = new BigDecimal(i);
result = result.multiply(a);
}
return result;
}
// n!/m!
public static BigDecimal n2m(int n, int m) {
BigDecimal result = new BigDecimal(n);
BigDecimal a;
for (int i = n - 1; i > m; i--) {
a = new BigDecimal(i);
result = result.multiply(a);
}
return result;
}
// n!/(n-m)! === a(n,m)
public static BigDecimal a(int n, int m) {
if (m == 0)
return new BigDecimal(1);
BigDecimal result = new BigDecimal(n);
BigDecimal a;
for (int i = n - 1; i > n - m; i--) {
a = new BigDecimal(i);
result = result.multiply(a);
}
return result;
}
// c(n,m) === a(n,m)/(m)!
public static BigDecimal c(int n, int m) {
if (m == 0)
return new BigDecimal(1);
if (m == n)
return new BigDecimal(1);
// 优化计算,避免大除大
if (m > n / 2)
return n2m(n, m).divide(n(n - m));
else
return a(n, m).divide(n(m));
}
}
#结果&结论
- 0~4: 0.8176930694561881
- 4~80: 0.14056818112756556
抽80次,出0~4次货的概率 高达94.9%、
出4次及以上的概率为 14%,其中出4次占9%
这样一看我还行,乐上加乐,没钱人的开心就是这么简单。