学习笔记45——n个骰子的点数(递归法,时间效率较低)

    xiaoxiao2023-10-27  147

    题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。 思路: 第一步——先统计出每个点数出现的次数 先把那个骰子分为两堆:第一堆只有一个;另一堆有n-1个。需要计算单独那个骰子有可能出现1~6的点数和剩下的n-1个骰子来计算点数和。接下来把剩下的n-1个骰子仍然分成两堆:第一堆只有一个;另一堆有n-1个。递归进行下去。 第二步——把每个点数出现的次数除以6的n次方,就能求出每个点数出现的概率 整体求n个骰子的点数和图例如下:(假设n=3) 核心代码如下:

    //递归法 void Probability(int number, int* pProbabilities); void Probability(int original, int current, int sum, int* pProbabilities); int maxValue = 6; void PrintProbability(int number){ if(number < 1) return; int maxSum = number * maxValue; int* pProbabilities = new int[maxSum - number + 1]; //定义一个长度为6*n-n+1的数组 for(int i = number; i <= maxSum; i++) pProbabilities[i - number] = 0; //初始化数组,将和为s的点数出现的次数保存到数组的s-n下标中,并初始化为0 //统计每个点数出现的次数,保存在pProbabilities数组中 Probability(number, pProbabilities); //把每个点出现的次数除以6的n次方,求出每个点数出现的概率 int total = pow((double)maxValue, number); for(int i = number; i <= maxSum; i++){ double ratio = (double)pProbabilities[i - number] / total; cout << i << ratio << endl; } delete[] pProbabilities; } void Probability(int number, int* pProbabilities){ for(int i = 1; i <= maxValue; i++) Probability(number, number, i, pProbabilities); } void Probability(int original, int current, int sum, int* pProbabilities){ if(current == 1) pProbabilities[sum - original]++; //此处sum为骰子总点数 else{ for(int i = 1; i <= maxValue; i++) Probability(original, current - 1, i + sum, pProbabilities); //i + sum为这一轮单独骰子的点数加上前面骰子的点数 } }
    最新回复(0)