骰子点数的概率
来源:互联网 发布:校园网络建设论文 编辑:程序博客网 时间:2024/04/30 11:41
题目
题目描述:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。输入:输入包括一个整数N(1<=N<=1000),代表有N个骰子。输出:可能有多组测试数据,对于每组数据,按照Sample Output的格式输出每一个可能出现的和S的概率。
前言
这道题目在《剑指offer》上有原题,但是感觉它上面分析的有些浅,起码连这个题目属于哪种类型都没有说出来,下面我讲一下我对这道题目的理解
解题思路
首先,我判断这是一道动态规划的题目,因为有重叠子问题,一个子问题在下一决策中会被多次用到
我们设有k个骰子,点数和为n时,n出现的次数为f(k,n),则可以分析出与k-1个骰子阶段的关系为:
当我有k-1个骰子时,再增加一个骰子,这个骰子的点数只可能为1,2,3,4,5,6.那有k个骰子得到点数和为n只有下述的6种情况:
- (k-1,n-1):第k个骰子投了点数1
- (k-1,n-2):第k个骰子投了点数2
- (k-1,n-3):第k个骰子投了点数3
- (k-1,n-4):第k个骰子投了点数4
- (k-1,n-5):第k个骰子投了点数5
- (k-1,n-6):第k个骰子投了点数6
所以,f(k,n) = f(k-1,n-1) + f(k-1,n-2) + f(k-1,n-3)+ f(k-1,n-4) + f(k-1,n-5) + f(k-1,n-6)
初始情况下,f(1,1) = f(1,2) = f(1,3) = f(1,4) = f(1,5) = f(1,6) =1
动态规划的标准代码
#include <stdio.h>#include <stdlib.h>#include <math.h>int main(void){int i, j, k, n, row, column;double count, **arr;while (scanf("%d", &n) != EOF) {// 动态申请二维数组row = n;column = 6 * n;arr = (double **)malloc((row + 1) * sizeof(double *));// 定义第一列(即每一行首地址)for (i = 0; i <= row; i ++) {arr[i] = (double *)malloc((column + 1) * sizeof(double));// 定义每一行}// 赋初值for (i = 1; i <= column; i ++) {if (i <= 6)arr[1][i] = 1.000;elsearr[1][i] = 0.000;}// 动态规划for (i = 2; i <= row; i ++) {for (j = 1; j <= column; j ++) {if (j > i * 6 || j < i) { // 超过最大or小于最小arr[i][j] = 0.000;} else {for (k = j - 6, arr[i][j] = 0; k < j; k ++) {if (k < 1) continue;elsearr[i][j] += arr[i - 1][k];}}}// 初始化,将i个骰子时不可能存在的点数置为0for (k = 0; k < i; k ++)arr[i][k] = 0.000;}// 打印输出for (i = row, count = pow(6, row); i <= column; i ++) {printf("%d %.3f\n", i, arr[row][i] / count);}printf("\n");}return 0;}
但是,九度提交竟然提示我超内存限制:
这道题内存限制为32M,也就是32768kb,我超出了72kb,蛋疼!
AC代码
考虑行数为2,用%的方法来保存上次的结果集即可,ac代码如下:
#include <stdio.h>#include <stdlib.h>#include <math.h>#define MAX 6int main(){int i, j, k, n;double count, **arr;while (scanf("%d", &n) != EOF) {// 动态申请二维数组arr = (double **)malloc(sizeof(double *) * 2);for (i = 0; i < 2; i ++) {arr[i] = (double *)malloc(sizeof(double) * (MAX * n + 1));}for (i = 1; i <= 6; i ++) // 初始化arr[1][i] = 1.000;for (i = 2; i <= n; i ++) {for (j = i; j <= i * 6; j ++) {arr[i % 2][j] = 0.000;for (k = j - 6; k < j; k ++) {if (k > 0) {arr[i % 2][j] += arr[(i + 1) % 2][k];}}}// 多谢wfxyjx的提醒,这里需要当有i个骰子时,不可能存在的点数重新赋值为0for (k = 0; k < i; k ++) {arr[i % 2][k] = 0.000;}}for (count = pow(6, n), i = n; i <= n * 6; i ++)printf("%d: %.3f\n", i, arr[n % 2][i] / count);printf("\n");free(arr);}return 0;}
- 骰子点数的概率
- 题目1255:骰子点数概率
- 三个骰子点数之和概率
- 骰子点数分布概率问题
- n个骰子的点数之和的概率
- 问题:骰子点数和能够到达2014的概率
- n个骰子点数和及各自出现的概率
- n个骰子的点数以及出现概率
- 剑指offer40--n个骰子点数和的概率
- n个骰子 点数和 概率计算
- 九度 题目1255:骰子点数概率
- n个骰子的点数
- n 个骰子的点数
- n个骰子的点数
- n个骰子的点数
- n个骰子的点数
- N个骰子的点数
- n个骰子的点数
- Flex开发ArcGIS问题集锦三:如何发布地图(二)
- Linux 如何禁止用户登录
- 不想创业失败?那就千万别做这16件事情!
- char 与 unsigned char的本质区别
- android的binder机制研究(C++部分)
- 骰子点数的概率
- autovue查看不在plm里面文件的
- android学习2--ListView的简单学习
- UBOOT引导Linux内核及向内核传递参数的方式
- 敏捷实践
- 张张催人泪下 图说“工人阶级”的心酸谋生路
- OS X Mountain Lion 系统配置 Apache+Mysql+PHP 详细教程
- 图像去噪
- 推荐一个免费的Firefox 抓全屏插件