主页 > imtoken钱包app安卓版 > 基于骰子点数,时间效率不够高

基于骰子点数,时间效率不够高

imtoken钱包app安卓版 2023-03-26 07:26:22

话题:

将n个骰子扔在地上,所有骰子向上面的点数之和为s。 输入n,打印出s所有可能取值的概率。

分析:

n个骰子点数,最小值为n,最大值为6n。根据排列组合,n个骰子所有点的排列数为

6^{n}

,需要先统计每个点出现的次数,再除以

6^{n}

,可以计算出每个点出现的概率。

基于骰子点数,时间效率不够高

先把n个骰子分成两堆:第一堆有1,第二堆有n-1。 第一堆可能有1~6个,我们需要计算每一种1~6的点数和剩下的n-1个骰子的点数之和。 接下来,剩下的n-1个骰子还是分成两堆:第一堆有1,第二堆有n-2。 将上一轮个人骰子和本轮个人骰子的点数相加,再将剩余的n-2个骰子相加btc骰子概率计算器,计算点数总和。 这是一个递归的思路,递归终止的条件是最后还剩一个骰子。

定义一个长度为6n-n+1的数组,将和为s的点出现的次数放入下标为sn的位置。

基于循环查找骰子点,时间性能好

递归里面有很多重复的计算,理解起来比较困难。 我不明白。 我们使用循环来解决这个问题。

设f(n,k)表示n个骰子,某一个骰子的总和为k的次数,如果n个骰子的结果为k,这个结果与n-1个骰子的结果相关,则有6种情况,第n个骰子可能出现1~6,那么前n-1个骰子会分别出现k-1~k-6,所以f(n,k)=f(n-1,k -1)+ f(n-1,k-2)+f(n-1,k-3)+f(n-1,k-4)+f(n-1,k-5)+f(n-1, k-6), 其中 n>0, k≤6n。 当初是怎样的? f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。 用递归的思维去分析,用循环自下而上的解决代码。

解决方案:基于骰子点数,时间效率不够高

package com.wsy;

btc骰子概率计算器_骰子的概率计算器_三个骰子点数概率

public class Main { public static int[] result; public static int maxValue = 6; public static void main(String[] args) { int n = 5; printProbability(n); } public static void printProbability(int n) { if (n < 1) { return; } result = new int[n * maxValue - n + 1];

三个骰子点数概率_btc骰子概率计算器_骰子的概率计算器

int maxSum = maxValue * n; for (int i = 1; i <= maxValue; i++) { probability(n, n, i); } int total = (int) Math.pow(maxValue, n); for (int i = n; i <= maxSum; i++) { System.out.println("s=" + i + "\tp=" + (1.0 * result[i - n] / total)); } } public static void probability(int original, int current, int sum) { if (current == 1) { result[sum - original]++; } else { for (int i = 1; i <= maxValue; i++) {

三个骰子点数概率_btc骰子概率计算器_骰子的概率计算器

probability(original, current - 1, i + sum); } } } }

基于循环查找骰子点btc骰子概率计算器,时间性能好

package com.wsy;
public class Main {
    public static int[] result;
    public static int maxValue = 6;
    public static void main(String[] args) {
        int n = 6;

btc骰子概率计算器_骰子的概率计算器_三个骰子点数概率

printProbability(n); } public static void printProbability(int n) { if (n < 1) { return; } result = new int[maxValue * n + 1]; // 投出第1个骰子 for (int i = 1; i <= maxValue; i++) {// f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1 result[i] = 1; } for (int i = 2; i <= n; i++) {// 依次投出第i个骰子 // 从后面向前更新result,因为投出第i个骰子后,[i,i*maxValue]之间的值都要更新,新增了一个骰子,可能构成的情况更多了 // [1,i]之间的值也要更新,增加了骰子,有的值就取不到了,比如n个骰子,sum骰子的概率计算器_btc骰子概率计算器_三个骰子点数概率

// 后面的值要用到前面的值在n-1时候的状态,如果先更新前面的值,后面的值在计算的时候,前面的值就是n时候的状态了 for (int j = i * maxValue; j >= 1; j--) { int temp = 0; // 计算f(n-1,j-1)+f(n-1,j-2)+f(n-1,j-3)+f(n-1,j-4)+f(n-1,j-5)+f(n-1,j-6),注意有的时候j小于6,累加不到j-6,就用0代替 for (int k = 1; k <= maxValue; k++) { temp += j > k ? result[j - k] : 0; } result[j] = temp; } } int total = (int) Math.pow(maxValue, n); for (int i = n; i <= n * maxValue; i++) { System.out.println("s=" + i + "\tp=" + (1.0 * result[i] / total)); } } }