LintCode——筛子求和

Posted wangcj2015

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LintCode——筛子求和相关的知识,希望对你有一定的参考价值。

描述:扔n个骰子,向上面的数字之和为 S 。给定 Given n,请列出所有可能的 S 值及其相应的概率。

样例:给定n=1,返回 [ [1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]

解题思路:假定有n个骰子,那么可投掷出的数字在n~6n之间,即S的取指在n~6n之间,n个骰子投掷会出现6的n次方种情况;我们采用递归思想,求n个骰子投出num的情况数的时,需要递归求n-1个骰子投出num-1,num-2,num-3...num-6的情况,而求n-1个骰子投出num-1的情况数的时候,需要递归求n-2个骰子投出num-2,num-3,num-4...,num-12的情况;依次类推,其中会有重复求解的过程,为了优化算法,我们采用动态规划技术来减少不必要的重复求解过程。使用HashMap<string,double>来存储已经计算好的情况数。这里String作为键,用以标记“x个骰子投出y”,值Double为情况数。

 1 public class Solution {
 2     /**
 3      * @param n an integer
 4      * @return a list of Map.Entry<sum, probability>
 5      */
 6     public List<Map.Entry<Integer, Double>> dicesSum(int n) {
 7         // Write your code here
 8         // Ps. new AbstractMap.SimpleEntry<Integer, Double>(sum, pro)
 9         // to create the pair
10         List<Map.Entry<Integer, Double>> list = new ArrayList<Map.Entry<Integer,Double>>(5 * n + 1);
11         Double pro = 0.0;
12         double total = Math.pow(6, n);
13         double conditions = 0;   
14         HashMap<String,Double> hashMap = new HashMap<>();
15         for(int i = n;i <= 6 * n;i++){
16             pro = 0.0;
17             conditions = findCombs(i, n,hashMap);
18             pro = conditions / total;
19             list.add(new AbstractMap.SimpleEntry<Integer, Double>(i,pro));
20         }
21         return list;
22     }
23     
24     public static double findCombs(int num,int n,HashMap<String, Double>hashMap){
25         //为了简化计算,假设每个骰子最小值为0,最大值为5,共n个骰子
26         double total = 0;
27         String key = String.valueOf(num) + "," + String.valueOf(n);
28         if(hashMap.containsKey(key)){//若前面已经计算过该状态则直接返回结果
29             return hashMap.get(key);
30         }
31         
32         if(num <= 0){
33             if(n >= 1)
34                 total = 0;
35             else
36                 total = 1;//0 个骰子得到0 是可以的
37         }
38         else{
39             //num >0
40             if(n < 1){
41                 total = 0;
42             }
43             else if(n == 1){
44                 if(num > 6)
45                     total = 0;
46                 else
47                     total = 1;
48             }
49             else{
50                 int ceil = num <= 6 ? num : 6;
51                 for(int i = 1;i <= ceil;i++){
52                     total += findCombs(num-i, n-1,hashMap);
53                 }
54             }
55         }
56         hashMap.put(key, total);
57         return total;
58     }
59 }

 


以上是关于LintCode——筛子求和的主要内容,如果未能解决你的问题,请参考以下文章

408 二进制求和

龙珠激斗大冒险掷筛子算法

使用筛子找到小于 LONG 数的素数

lintcode-720重排带整数字符串

以下代码片段的算法复杂度

js中的投掷筛子的小游戏