首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >golang刷leetcode 技巧(34)n个骰子的点数

golang刷leetcode 技巧(34)n个骰子的点数

作者头像
golangLeetcode
发布2022-08-02 18:46:16
发布2022-08-02 18:46:16
3830
举报

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

你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。

示例 1:

输入: 1

输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]

示例 2:

输入: 2

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

限制:

1 <= n <= 11

解题思路

1,这是一个动态规划题目

2,假设有i个骰子,可以拼出的点数为i,i+1,i+2,......,i*6,共2*i-i+1个

3,i取值范围是1...n

4, 用dp[i][j],表示,i个骰子,点数和为j的组合个数

5,状态转移方程为

dp[i][j]=sum(dp[i-1][j-k]) k=1,2,3,4,5,6

6,由于用到了i-1,所以递增

7,结果取,i=n那一列,j变化范围从 i到2*i的数据,除以 pow(6,n)

代码实现

代码语言:javascript
复制
func twoSum(n int) []float64 {
    var r []float64
    dp:=make([][]int,n+1)
    for i:=0;i<n+1;i++{
        dp[i]=make([]int,n*6+1)
    }

    s:=pow(6,n)

    //1  1...6
    //2  2...12 
    for i:=1;i<=6;i++{
        dp[1][i]=1
    }

    for i:=2;i<=n;i++{
        for j:=i;j<=i*6;j++{
            for k:=1;k<=6;k++{
                if j>k{
                   
                    dp[i][j]+=dp[i-1][j-k]
                     fmt.Println( dp[i][j],":",i,j,"=>",i-1,j-k)
                }
            }
            if j==i*6{
            //    dp[i][j]=1
            }
            
        }
    }
    for  j:=n;j<=n*6;j++{
        r=append(r,float64(dp[n][j])/float64(s))
    }
     fmt.Println(dp[n][n:n*6+1])
    fmt.Println(dp,s)
    return r

}


func pow(x,y int)int{
    r:=1
    for i:=0;i<y;i++{
       r*=x
    }
    return r
}


/**
解题思路
dp[i][j]表示当n=i时,和为j出现的排列情况总数;
状态转移方程:dp[i][j]=dp[i-1][j-1]+dp[i-1][j-2]+dp[i-1][j-3]+dp[i-1][j-4]+dp[i-1][j-5]+dp[i-1][j-6];
初始条件:dp[1][1]=dp[1][2]=dp[1][3]=dp[1][4]=dp[1][5]=dp[1][6]=1;

代码
class Solution {
public:
    vector<double> twoSum(int n) {
        vector<vector<int>>dp(n+1,vector<int>(6*n+1,0));
        double num=pow(6,n);
        vector<double>res(5*n+1,1/(double)6);
        //初始状态
        for(int i=1;i<=6;i++)dp[1][i]=1;
        for(int i=2;i<=n;i++){      //从2到n计算dp
            for(int j=i;j<=i*6;j++){  //表示当n=i时候的点数和取值从i到6i
                for(int k=1;k<=6;k++){  //dp[i][j]=dp[i-1][j-1]+dp[i-1][j-2]+dp[i-1][j-3]+dp[i-1][j-4]+dp[i-1][j-5]+dp[i-1][j-6];
                    if(j-k>0)dp[i][j]+=dp[i-1][j-k]; //第i个骰子点数一定比i-1个骰子点数大
                    if(i==n)res[j-i]=dp[i][j]/num;
              }
            }
        }        
        return res;
    }
};
*/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档