剑指 Offer 60. n个骰子的点数 + 动态规划 + 空间优化

剑指 Offer 60. n个骰子的点数

Offer_60

题目详情

题解分析

package com.walegarrett.offer;


/**
 * @Author WaleGarrett
 * @Date 2021/2/12 18:29
 */

/**
 * 题目描述:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
 * 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
 */

import java.util.Arrays;

/**
 * 动态规划:dp[i][j]表示掷n个骰子后,点数总和为j出现的次数
 */
public class Offer_60 {
    public double[] dicesProbability(int n) {
        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<=6*i; j++){
                for(int k=1; k<=6 && j-k>0; k++)
                    dp[i][j] += dp[i-1][j-k];
            }
        }
        double allP = Math.pow(6,n);
        double[] result = new double[6*n-n+1];
        for(int i=n; i<=6*n; i++){
            result[i-n] = dp[n][i] * 1.0 / allP;
        }
        return result;
    }
}

空间优化

/**

 * 动态规划:空间优化
 */
class Offer_60_1 {
    public double[] dicesProbability(int n) {
        int[] dp = new int[70];
        Arrays.fill(dp,0);
        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 k=1; k<=6 && j-k>=i-1; k++)
                    dp[j] += dp[j-k];
            }
        }
        double allP = Math.pow(6,n);
        double[] result = new double[6*n-n+1];
        for(int i=n; i<=6*n; i++){
            result[i-n] = dp[i] * 1.0 / allP;
        }
        return result;
    }
}

题解参考:【n个骰子的点数】:详解动态规划及其优化方式

posted @ 2021-02-13 11:46  Garrett_Wale  阅读(69)  评论(0编辑  收藏  举报