一.题目描述

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

二.题解

  《剑指offer》上给出的两种方法,尤其是代码,晦涩难懂且没有注释。而n个骰子的问题实质就是一个动态规划问题,所以文本主要从动态规划的角度来求解这个问题。首先该问题具备DP的两个特征:最优子结构性质和子问题的重叠性。具体的表现在:(1)n个骰子的点数依赖于n-1个骰子的点数,相当于在n-1个骰子点数的基础上再进行投掷。(2)求父问题的同时,需要多次利用子问题。由此定义状态转移方程为$f(n,k)$表示$n$个骰子点数和为$k$时出现的次数,于是可得:

$$ 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(n-1,k-i)$表示的是第n次掷骰子时,骰子的点数为$i$对应的情况,所以从$k-1$到$k-6$分别对应第n次掷骰子时骰子正面为$1$到$6$的情况。而初始状态可以定义为:

$$ f(1,1) = f(1,2) = f(1,3) = f(1,4) = f(1,5) = f(1,6) = 1 $$

所以根据这两个方程,给出的实现代码如下:

#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#include<stack>
#define MAX_NUM 100
using namespace std; void FindSum(int n)
{
if(n <= 0)
return;
int sum = 0;
int arr[n + 1][6 * n + 1];
memset(arr,0,sizeof(arr));
for(int i = 1; i <= 6; i++)//初始状态
arr[1][i] = 1;
for(int i = 2; i <= n; i++)//状态转移方程
{
for(int j = i; j <= 6*i; j++)//注意j的范围受i影响
{
arr[i][j] += (arr[i - 1][j - 1] + arr[i - 1][j - 2] + arr[i - 1][j - 3] + arr[i - 1][j - 4] + arr[i - 1][j - 5]
+arr[i - 1][j - 6]);
}
}
//输出结果
for(int i = n; i <= 6 * n; i++)
{
//cout<<"骰子的和为 "<<i<<" 时,对应的次数为:"<<arr[n][i]<<endl;
sum += arr[n][i];
}
cout<<n<<"个骰子总共的次数为 "<<sum<<endl;
for(int i = n; i <= 6 * n; i++)
{
cout<<"骰子的和为 "<<i<<" 时,对应的频率为:"<<(arr[n][i] * 1.0 / sum)<<endl;
} }
int main()
{
int n;
cout<<"请输入骰子的个数:"<<endl;
cin>>n;
FindSum(n);
}

此处的代码只是朴素dp的实现,用动态规划来解释,感觉比书上好理解多了....

参考:https://blog.csdn.net/k346k346/article/details/50988681

《剑指offer(第二版)》面试题60——n个骰子的点数的更多相关文章

  1. 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树

    一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ...

  2. 经典面试题目——找到第n个丑数(参考《剑指offer(第二版)》面试题49)

    一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如 ...

  3. 《剑指offer(第二版)》——面试题36:二叉搜索树与双向链表

    具体的题目大意和参考思路在此处不详述(见<剑指offer>),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法. 方法1(递归法): 代 ...

  4. 《剑指offer(第二版)》面试题64——求1+2+...+n

    一.题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句 (即三元运算符,A? B : C) 二.题解 虽然求和问 ...

  5. 结合《剑指offer(第二版)》面试题51来谈谈归并排序

    一.题目大意 给定一个数组A,对于数组A中的两个数字,如果排在前面的一个数字大于(必须大于,等于不算)后面的数字,则这两个数字组成一个逆序对.要求输出数组A中的逆序对的总数.例如,对于数组{7,5,6 ...

  6. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  7. 剑指offer第二版-10.斐波那契数列

    面试题10:斐波那契数列 题目要求: 求斐波那契数列的第n项的值.f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n>1 思路:使用循环从下往上计算数列. 考点:考察对递归 ...

  8. 剑指offer第二版-5.替换空格

    面试题5:替换空格 题目要求: 实现一个函数,把字符串中的每个空格都替换成“%20”,已知原位置后面有足够的空余位置,要求改替换过程发生在原来的位置上. 思路: 首先遍历字符串求出串中空格的数量,求出 ...

  9. 剑指offer第二版-3.数组中重复的数

    面试题3:数组中重复的数 题目要求: 在一个长度为n的数组中,所有数字的取值范围都在[0,n-1],但不知道有几个数字重复或重复几次,找出其中任意一个重复的数字. 解法比较: /** * Copyri ...

随机推荐

  1. linux系统中文件的权限

    查看文件权限的语句: 在终端输入:ls -l xxx.xxx (xxx.xxx是文件名) 那么就会出现相类似的信息,主要都是这些:-rw-rw-r-- 一共有10位数 其中: 最前面那个 - 代表的是 ...

  2. 关于SpringMVC的配置流程以及一些细节

    首先说道SpringMvc是什么,SpringMVC是Spring框架里面的一个子框架,它对网站前后端的代码分层做了一套实现,这套实现给我们带来了几个好处,首先第一,SpringMVC实现了一个请求对 ...

  3. git怎么fork一个仓库并pull request

    一.使用git push <-----------就是这个玩意 1.设置用户信息 当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址. 这样做很重要,因为每一个 Git 的提交都会 ...

  4. c/c++ 栈与队列实现车库的出入与收费

      /* 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出.汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列 (大门在最南端,最先到达的第一辆车停放在车场的最北段),若停车厂内 ...

  5. tomcat下服务启动失败原因

    Tomcat启动成功,输入网址后可以显示小黄猫界面,但是在Tomcat下的服务却启动不成功,显示404(以Jenkins为例,运用多种方式查看原因) 注:1.单启动Tomcat服务是可以启动成功的. ...

  6. re模块(正则表达式)

    re,findall("匹配正则","内容") #所有满足条件的结果都返回到一个列表里 ret = re.search(“匹配规则”,“内容”) #返回 匹配到 ...

  7. Day02_Python基础学习今日总结

    1.模块(库):是别人写好的函数封装成一个名字,内部有丰富的功能可以直接调用.分为标准库和第三方库.标准库直接导入即可使用,而第三方库需要下载安装才能用. 2.在项目中导入库时,自建的文件名不能喝库名 ...

  8. Vue小技巧-懒加载

    Vue懒加载包括图片懒加载与路由懒加载 1.图片懒加载: 首先安装 vue-lazyload包 然后导入并加载事先下载好的加载图片 import VueLazyLoad from 'vue-lazyl ...

  9. 《Spring实战》读书笔记——Spring简介

    欢迎大家关注我的微信公众号,共同交流Java相关技术! 使用Spring的目的 Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能 ...

  10. postman连续添加多个订单&jmeter快速审核添加订单

    预期效果:添加多个订单,并审核(半自动?) 1.postman添加多个订单 post请求(postman基础的操作比较简单,网上有很详细的解说),单个接口保存[save] 单个接口保存[save],点 ...