之前 javaeye 网站上有人写过 3颗骰子能掷出多少种结果 的一道面试题,用了面向对象的思考方式,后来某天深夜自己想了又想,发现可以把这个问题转化为数学模型,用金字塔模型,再采用逆推推出了 N个骰子掷出的和的概率算法。
1颗骰子,一共6面,每一面掷出的概率都一样,在1维空间中表示,相当于造6层金字塔的一条边
2颗骰子,在2维空间中表示。。。 (画图画了好久,直接用画图板手工绘制的,没有3d效果,大家想象成3d的吧)
下面表示的是4颗骰子映射出来的4维空间模型。怎么理解呢? 就在3维空间上加一个时间吧,第一座金子公元前2000年开始建造,每年造一层,第二座金字塔公元前1999年开始建造,第三座金字塔公元前1998年开始建造,到了公园前1995年的时候,就变成下面这种状态了。
5颗骰子,依次类推,5维空间的表示,再加一个地点吧,公园前1995年的时候在埃及造了上面4维空间中的这些金字塔,一共126块砖,同年在玛雅造了5座金字塔,(假设玛雅比埃及晚造1年),其它地区的金子塔也在建造之中,都依次晚造1年。这样就形成了一个类似金子塔阶梯的5维空间。
同样,6维,7维……都和骰子投掷出来的和的概率相对应。如果把上面的每块砖都用数组来标记,就变成下面的形式:
再次提炼出数字规律
1颗:1,1,1,1,1,1
2颗:1,2,3,4,5,6
3颗:1,3,6,10,15,21
4颗:1,4,10,20,35,56
5颗:1,5,15,35,70,126
发现规律了吧,每组数中的数字都是上一组数字前几位数的和。
下面贴上java实现程序,灵感闪现,仓促下笔,算法不是很简洁,没有完全构造对象,用了数组和递归,可能阅读比较晦涩。
package org.vv.algorithm.number;
import java.util.Map;
import java.util.TreeMap;
/**
* 计算 骰子的组合 概率 问题
* @author 俞立全
* @version 2009-10-20
*/
public class A {
/**
* 初始化定义骰子的个数
*/
private static int[] n = {1,1,1,1,1,1};
//排列,组合
/*
* 骰子的组合就是求和的概率,如2颗骰子 出现和为2的概率是1,3的概率是2,4的概率是3,5的概率是4,6的概率是5,7的概率是6 ,概率的总和也就是骰子的组合。
*/
//1,1,1,1,1,1
//6,5,4,3,2,1
//21,15,10,6,3,1
//56,35,20,10,4,1
//126,70,35,15,5,1
//上面每一个结果都是
/**
* 计算骰子组合的总数(排列)
* @para