目录
题目描述
把n个骰子仍在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
测试用例
- 功能测试(1、2、3、4个骰子的各点数的概率)
- 特殊输入测试(输入0)
- 性能测试(输入较大的数字,如11)。
题目考点
- 考察应聘者的数学建模能力。
- 考察应聘者对递归和循环的性能的理解。
解题思路
用两个数组来存储骰子点数的每个总数出现的次数(动态规划数组)
n个骰子,n轮
在第一轮循环中,第一个数组中的第n个数字表示骰子和为n出现的次数
在下一轮循环中,我们加上一个新的骰子,此时和为n的骰子出现的次数应该等于上一轮循环中骰子点数和为n-1、n-2、n-3、n-4、n-5与n-6的次数的总和
依次类推求解。
对于n个骰子,有以下对应:
下标 i | 1 | 2 | 3 | 4 | 5 | 6 | … | m | … | 最大值为6 * n |
上一轮 p[0] | 存储的内容表示当前轮和为m出现的次数 | |||||||||
新一轮 p[1] | 增加一个骰子,新一轮和为m出现次数p[1][m] = p[0][m-1] + p[0][m-2] + ……+ p[0][m-j], m >= j 并且 j <= 6 |
参考解题
package Sword;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 骰子之和
* 动态规划
* @author tyler
*
*/
public class dicesSumSolution {
// 骰子最大值
int maxValue = 6;
public List<Map.Entry<Integer, Double>> dicesSum(int n) {
// AbstractMap<K,V>, 此类提供了Map接口的骨架实现,以尽量减少实现此接口所需的工作量。
List<Map.Entry<Integer, Double>> result = new
ArrayList<AbstractMap.Entry<Integer, Double>>();
if (n < 0 ) {
return result;
}
// 这里一定要用long型,不能用int型,数大了之后会造成int型溢出
long[][] probabilities = new long[2][maxValue * n + 1];
// 数组转换标志
int flag = 0;
// 初始化第一轮数组p[0],出现1,2,3,4,5,6 的次数为1
for (int i = 1; i <= maxValue; ++i) {
probabilities[flag][i] = 1;
}
// 逐个增加骰子,直到总共n个骰子
for (int k = 2; k <= n; k++) {
// 新一轮和为i = 0,1,2,……,k-1的次数不可能存在,令p[1][i] = 0;
for (int i = 0; i < k; i++) {
probabilities[1 - flag][i] = 0;
}
// 新一轮可能出现的数字为k,k+1,……,k * maxValue,逐个更新其次数
for (int i = k; i <= maxValue * k; i++) {
// 首先清空新一轮数组,为更新做准备
probabilities[1 - flag][i] = 0;
// 新一轮和为i等于上一轮的几个和为i-1,i-2,……,i-j , i >= j 并且 j < maxValue 的总和
for (int j = 1; j <= i && j <= maxValue; j++) {
probabilities[1 - flag][i] += probabilities[flag][i - j];
}
}
// 增加完一个骰子,开始下一个骰子,p[1]变成p[0]
flag = 1 - flag;
}
double total = Math.pow(maxValue, n);
for (int i = n; i <= maxValue * n; i++) {
result.add(new AbstractMap.SimpleEntry<Integer, Double>(i, probabilities[flag][i] / total));
// AbstractMap.SimpleEntry<K,V> 保存密钥和值的条目。 该值可以使用setValue方法更改。
//这个类促进了构建自定义地图实现的过程。 例如,在方法Map.entrySet().toArray中返回SimpleEntry个实例的数组可能很方便
}
return result;
}
}