[LeetCode Brushing Notes (Seventy-Four)] 60. The number of n dice points

This article is published by the official account [Developing Pigeon]! Welcome to follow! ! !


Old Rules-Sister Town House:

One. topic

(1) Question stem

        Throw n dice on the ground, and the sum of the points on the upward side of all dice is s. Enter n to print out the probabilities of all possible values ​​of s.

        You need to use an array of floating-point numbers to return the answer, where the i-th element represents the probability of the i-th smallest in the set of points that can be thrown by the n dice.


(Two) example

Example 1:

输入: 1
输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]

Example 2:

输入: 2
输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]

two. answer

(1) Ideas

        It turned out to be a DP issue again. As long as there is an increase or decrease in the title, you must think about whether DP can do it. The sum of the points of all the dice is superimposed one by one, so the sum of the points of the next dice is equal to the number of the previous dice and the number between + 1 to 6. This forms the DP state transition equation. Therefore, the conversion relationship between the various stages has been found, now let’s analyze what is the last stage? The question requires the number of times each point appears after n dice are thrown. Therefore, the state of the stage is the number of times the nth die and the number j appears. Therefore, a two-dimensional DP array is set to represent it. The idea is formed, and the specific code does not need to be explained.

        The space can be further optimized, and it can be achieved using only one-dimensional arrays, but if you stack in ascending order, the previous numbers will be overlapped, and if the covered numbers are used by other numbers, DP will not be achieved. Therefore, we use reverse order to stack, so that even if we want to cover the previous number, it has already been used up by other numbers, so don't worry.

(Two) code

Not optimized:

class Solution {
    
    
    public double[] dicesProbability(int n) {
    
    
        // s是n个骰子的点数之和,n个骰子共有?种点数和种类
        // 骰子的结果是对称的,
        // dp,每次骰子的点数都是增加的,注意,dp的题目的关键字是递增关系或者递减关系
        // 下一次某个点数等于上6个点数之和
        int[][] dp = new int[n+1][70];
        // 第一次
        for(int i = 1; i <= 6; ++i){
    
    
            dp[1][i] = 1;
        }
        // 从第二个骰子开始
        for(int i = 2; i <= n; ++i){
    
    
            // 下一个骰子的可能点数和
            for(int j = i; j <= i*6; ++j){
    
    
                // 前一个骰子 再加上1- 6 等于下一个骰子可能的骰子总和
                for(int z = 1; z <= 6; ++z){
    
    
                    if((j-z) < (i-1)){
    
    
                        break;
                    }
                    dp[i][j] += dp[i-1][j-z];
                }
            }
        }
        double[] out = new double[5*n+1];
        int i = 0;
        for(int times : dp[n]){
    
    
            if(times == 0) continue;
            out[i++] = (double)(times / Math.pow(6, n));
        }
        return out;
    }
}

optimization:

class Solution {
    
    
    public double[] twoSum(int n) {
    
    
    	int dp[]=new int[70];
 		for (int i=1;i<=6 ;i++ ) {
    
    
 			dp[i]=1;
 		}
 		for (int i=2;i<=n ;i++ ) {
    
    
 			for (int j=6*i;j>=i ;j-- ) {
    
    
 				dp[j]=0;
 				for (int cur=1;cur<=6 ;cur++ ) {
    
    
 					if (j-cur<i-1) {
    
    
 						break;
 					}
                     dp[j]+=dp[j-cur];
 				}
 				
 			}
 		}
 		double all=Math.pow(6,n);
        double[] res=new double[5*n+1];
 		for (int i=n;i<=6*n ;i++ ) {
    
    
 			res[i-n]=(dp[i]*1.0/all);
 		}
 		return res;
    }
}

Guess you like

Origin blog.csdn.net/Mrwxxxx/article/details/113732568