1. 程式人生 > >n個骰子的點數以及出現概率

n個骰子的點數以及出現概率

//把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,打印出s的所有可能
//的值出現的概率。
#include "stdio.h"
#include "cmath"
#include "helper.h"
using namespace std;

//方法1:遞迴思路。把骰子分成兩堆,一堆1個,另一堆n-1個。
int diceSurface = 6;

void probabilityRecursively(int current, int sum,
	int* appearanceCount)
{
	if (current == 1)
		appearanceCount[sum]++;
	else
	{
		for (int i = 1; i <= diceSurface; ++i)
			probabilityRecursively(current - 1, i + sum, appearanceCount);
	}
}

void probability(int* appearanceCount, int n)
{
	for (int i = 1; i <= diceSurface; ++i)
		probabilityRecursively(n, i, appearanceCount);

}
void printAllProbability0(int n)
{
	if (n < 1)
		return;

	int maxSum = n * diceSurface;
	int* appearanceCount = new int[maxSum + 1]; //不會初始化為0

	for (int i = 0; i <= maxSum; i++)
		appearanceCount[i] = 0; //初始化

	probability(appearanceCount, n);

	int totalProbability = pow(diceSurface, n);
	for (int i = n; i <= maxSum; i++)
		printf("P(%d): %d/%d\n", i, appearanceCount[i], totalProbability);

	delete[] appearanceCount;
}


//兩個陣列交替進行,有點類似動態規劃的意思。
void printAllProbability1(int n)
{
	if (n < 1)
		return;

	int maxSum = n * diceSurface;
	int* appearanceCount[2];

	appearanceCount[0] = new int[maxSum + 1];
	appearanceCount[1] = new int[maxSum + 1];

	for (int i = 0; i <= maxSum; ++i)
	{
		appearanceCount[0][i] = 0;
		appearanceCount[1][i] = 0;
	}

	int flag = 0;
	for (int i = 1; i <= diceSurface; i++)
		appearanceCount[flag][i] = 1; 

	for (int k = 2; k <= n; ++k)
	{
		for (int i = 0; i < k; ++i)
			appearanceCount[1 - flag][i] = 0;

		for (int i = k; i <= maxSum; ++i)
		{
			appearanceCount[1 - flag][i] = 0;
			for (int j = 1; j <= i && j <= diceSurface; ++j)
				appearanceCount[1 - flag][i] += appearanceCount[flag][i - j];
		}
		flag = 1 - flag;
	}


	int totalProbability = pow(diceSurface, n);
	for (int i = n; i <= maxSum; i++)
		printf("P(%d): %d/%d\n", i, appearanceCount[flag][i], totalProbability);

	delete[] appearanceCount[0];
	delete[] appearanceCount[1];
}

int main()
{
	int n = 3;
	printAllProbability1(n);
	return 0;
}

這道題很棒!

相關推薦

n點數和及各自出現概率

題目:把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。 這道演算法題可採取動態規劃法來求解。鑑於《劍指Offer》中對該題的解法晦澀難懂,尤其是程式碼,也沒有指明其解題的思路本質上就是動態規劃,所以提出自己的理解和

N點數之和的分佈

將N個均勻的骰子,扔在地上,求點數之和的分佈。 因為是分佈,自然是求N個篩子之和等於M的概率,p(m) p(m) = fre(n,m)/sum fre(n,m)是指n個骰子扔出m個點數的 總的可能情況,這個就相當於組合數,只是限制了每個骰子的點數在1-6之間。 sum是n

n點數以及出現概率

//把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,打印出s的所有可能 //的值出現的概率。 #include "stdio.h" #include "cmath" #include "helper.h" using namespace std; //方法1:

n點數出現概率-動態規劃

這幾天在看劍指offer的時候發現,求n個骰子個點數和這個問題是發現書中講的不是很清楚,於是查詢資料,覺得下面講的比較透徹,記錄如下: 題目:把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。 宣告思想非原創!只因動態規劃思

n點數出現概率- 動態規劃

題目:把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。 宣告思想非原創!只因動態規劃思想的使用很好,記下! 分析:動態規劃就是分階段考慮問題,給出變數,找出相鄰階段間的關係。具體定義給忘了。 1.現在變數有:骰子個數,點

n點數之和的概率

n個骰子的點數。把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。 思想:F(n,s) = F(n-1,s-6)+F(n-1,s-5)+F(n-1,s-4)+F(n-1,s-3)+F(n-1,s-2)+F(n-1,s-1); #i

《劍指offer》 面試題43 n點數 (java)

r+ nal ret 次循環 分而治之 源碼 ava 面試 ble 引言:寫這篇文章的初衷只是想做個筆記,因為這道題代碼量有點大,有點抽象,而書上並沒有詳細的註釋。為了加深印象和便於下次復習,做個記錄。 原題:把n個骰子扔到地上,所有骰子朝上一面的點數之後為s. 輸入n,打

劍指Offer面試題43(Java版):n點數

pac pos max mod ins pri class pro bili 題目:把n個骰子仍在地上。全部骰子朝上一面的點數之和為s,輸入n,打印出s的全部可能的值出現的概率。 解法一:基於遞歸求骰子的點數,時間效率不夠高 如今我們考慮怎樣統計每個點數出現的次數。要向

n點數(Java實現)

本題為劍指offer面試題43 沒有找到牛客網的測試例題 題目:把n個骰子仍在地上,所有骰子朝上一面的點數之和為s,輸入n,打印出s的所有可能的值出現的概率。 解法一:基於遞迴求骰子的點數,時間效率不夠高 現在我們考慮如何統計每一個點數出現的次數。要向求出n個骰

點數之和概率

題目出自美團點評線上筆試題,求三個骰子的點數之和概率最大的是? 思路:三個骰子點數之和的範圍是3~18,越靠近兩邊出現的概率越小,因此點數和概率最大的情況應該出現在中間位置。計算中間9,10,11,1

n點數

把n個骰子扔在地上,所有骰子朝上一面的點數之和為s,輸入n,打印出s的所有可能出現的概率 思路:遞迴一般是自頂向下的分析求解,而迴圈則是自底向上,佔用更少的空間和更少的時間,效能較好。定義一個二維陣列,第一次擲骰子有6種可能,第一個骰子投完的結果存到probabilitie

【劍指offer】面試題43:n點數

第一種思路是,每個骰子的點數從最小到最大,假設為1-6,那麼所有的骰子從最小1開始,我們假設一種從左向右的排列,右邊的最低,索引從最低開始,判斷和的情況。 def setTo1(dices, start, end): for i in range(start, end)

劍指offer:n點數(java)

題目:把n個骰子仍在地上,所有骰子朝上一面的點數之和為s,輸入n,打印出s的所有可能的值出現的概率。     骰子一共6個面,每個面上都有一個點數,對應的是1-6之間的一個數字。所以n個骰子的點數和的最小值是n,最大值為6n.另外根據排列組合的知識,我們還知道n個骰子的所有

面試題43: n點數

原題:把n個骰子扔到地上,所有骰子朝上一面的點數之後為s. 輸入n,打印出s所有可能的值出現的概率。(每個骰子6個面,點數從1到6) 解法一:基於遞迴,時間效率不高 遞迴的思想一般是分而治之,把n個骰子分為第一個和剩下的n-1個。先計算第一個骰子每個點數出現的次數,再

《劍指offer》:[43]N點數

題目:把N個骰子扔在地上,所有骰子朝上一面的點數之和為S,輸入N,打印出S的所有可能的值出現的概率。 分析:對於6點的N個骰子來講,其和S的最小值為N,最大值為6N。要得到和S出現的概率,就得得到和S出現的次數,然後用某一S出現的次數/S的所有可能性=S出現的概率。對於骰

劍指offer 面試題43—n點數

題目: 把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。 解法一:遞迴        玩過麻將的都知道,骰子一共6個面,每個面上都有一個點數,對應的數字是1到 6之間的一個數字。所以,n個骰子的點數和的最小值為n,最大值為6n

《劍指offer》第六十題(n點數

original double 出現 ostream 使用 col ren str current // 面試題60:n個骰子的點數 // 題目:把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,打印出s // 的所有可能的值出現的概率。 #incl

LightOJ 1248 - Dice (III) 給一個質地均勻的n, 求投擲出所有點數至少一次的期望次數。(概率

pri std printf 有一個 return main tdi algorithm style 題意:http://www.lightoj.com/volume_showproblem.php?problem=1248   投擲出第一個未出現的點數的概率為n/n =

使用pygal統計投擲N之後點數的分布情況

可視化 clas file gpo mes 計算 result 完整 次數 一、環境信息 python版本:2.7.13 pygal版本:2.4.0 pygal安裝:pip install pygal 從python官方完整下載的最新的python版本自帶pip 二、具

題目1255:點數概率(動態規劃)

提交總是Wrong Answer,覺得自己的程式碼是沒有問題的,如4個骰子的和為4的情況只能有一個,就是4個全部為1 題意:給出n個骰子,計算所有骰子朝上一面的點數之和為S對應的概率 思路:用dp(i,j)表示i個骰子和為j時的概率,有dp(i,j)=(dp(i-1,j-1