N个骰子的点数

题目        

把n个骰子仍在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所以可能的值出现的概率。(骰子有六个面)

思路

N个骰子最小的点数为n,最大的点数为6n,一共有6n-n+1种可能。

总的可能的次数为6^n

思路一

基于递归的思路

把n个骰子分为1个和n-1个,对于一个骰子来说,它有1-6六种可能。

然后把n-1个骰子在分为1个和n-1个,这一个也有六中可能,加上上一次的一个骰子出现的点数。

所以可以基于递归写出代码,因为有重复计算,所以时间复杂度高。

思路二

基于循环的思路

对于一个骰子,1,2,3,4,5,6出现的次数都为1.

对于两个骰子,也就是新增加一个骰子,对于5出现的次数,就是一个骰子时4出现的次数+一个骰子时3出现的次数+一个骰子时2出现次数+一个骰子时1出现次数。‘

对于n个骰子,对于出现的次数,就等于n-1个骰子时k-1出现次数+n-1个骰子时k-2出现次数+……+n-1个骰子时k-6出现次数。

基于这个思想,用两个数组来表示骰子出现的次数。

代码

思路一

public static void printProbability(int number){
    int[] datas = new int[6 * number - number + 1];
    for(int i = 0;i < datas.length;i++)datas[i] = 0;

    probability(number,datas);

    int total = (int)Math.pow(6,number);

    for(int i = 0;i < datas.length;i++){
        double probability = (double)datas[i] / total;
        System.out.println(i+number + "   :    " + probability );
    }
}
public static void probability(int number,int[] datas){
    for(int i = 1;i <= 6;i++){
        probability(number,number,i,datas);
    }
}
public static void probability(int original,int current,int sum,int[] datas){
    if(current == 1){
        datas[sum - original]++;
    }else {
        for(int i = 1;i <= 6;i++){
            probability(original,current - 1,i + sum,datas);
        }
    }
}

思路二

public static void printProbability(int number){

    int[][] datas = new int[2][6 * number + 1];

    for(int i = 0;i < datas[0].length;i++){

        datas[0][i] = 0;

        datas[1][i] = 0;

    }

    int flag = 0;

    for(int i = 1;i <= 6;i++){

        datas[flag][i] = 1;

    }

    for(int k = 2;k <= number;k++){

        for(int i = 0;i < k;i++){

            datas[1 - flag][i] = 0;

        }

        for(int i = k;i <= 6 * k;i++){

            datas[1 - flag][i] = 0;

            for(int j = 1;j <= i && j <= 6;j++){

                datas[1 - flag][i] += datas[flag][i - j];

            }

        }

        flag = 1 - flag;

    }

    int total = (int)Math.pow(6,number);

    for(int i = number;i <= 6 * number;i++){

        double probability = (double)datas[flag][i] / total;

        System.out.println(i + "     :     " + probability);

    }

}

总结

本题不管是基于递归与基于循环的解法,都需要有一定的抽象建模的能力,可以先举例按步计算骰子个数较少的情况,模拟计算机计算过程,发现计算过程的规律,然后在编程。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值