zoukankan      html  css  js  c++  java
  • 骰子点数的概率

    题目

    题目描述:
    把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种情况:
    1. (k-1,n-1):第k个骰子投了点数1
    2. (k-1,n-2):第k个骰子投了点数2
    3. (k-1,n-3):第k个骰子投了点数3
    4. (k-1,n-4):第k个骰子投了点数4
    5. (k-1,n-5):第k个骰子投了点数5
    6. (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;
    			else
    				arr[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;
    						else
    							arr[i][j] += arr[i - 1][k];
    					}
    				}
    			}
    		}
    
    		// 打印输出
    		for (i = row, count = pow(6, row); i <= column; i ++) {
    			printf("%d %.3f
    ", i, arr[row][i] / count);
    		}
    		printf("
    ");
    	}
    
    	return 0;
    }

    但是,九度提交竟然提示我超内存限制:



    这道题内存限制为32M,也就是32768kb,我超出了72kb,蛋疼!

    AC代码

    考虑行数为2,用%的方法来保存上次的结果集即可,ac代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #define MAX 6
     
    int 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];
                        }
                    }
                }
            }
     
            for (count = pow(6, n), i = n; i <= n * 6; i ++)
                printf("%d: %.3f
    ", i, arr[n % 2][i] / count);
     
            printf("
    ");
            free(arr);
        }
     
        return 0;
    }
     
    /**************************************************************
        Problem: 1255
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:290 ms
        Memory:3404 kb
    ****************************************************************/


  • 相关阅读:
    本地向GitHub提交403错误解决办法(自己的创建的项目)
    zepto-ajax跨域请求接口 jsonp 静态页面数据展示
    自定义获取url方法
    使用swiper 轮播插件ajax 请求加载图片时,无法滑动问题
    背景透明,文字不透明解决办法
    js DOM Element属性和方法整理----转载
    图像处理作业5——SIFT算法与全景图像生成
    应用连续高斯模糊后得到的σ是多少?
    Pandas学习笔记——综合练习
    Pandas学习笔记5——合并
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3146792.html
Copyright © 2011-2022 走看看