把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s。输入n,打印出s的所有可能的值和出现的概率。
解法二:基于循环求骰子点数,比递归算法更加高端大气上档次
具体代码如下,有详细注释。
1 ////基于循环求骰子点数// 2 int g_MaxValue = 6 ;//骰子的点数个数 3 void PrintProbability(int number)//number 为骰子个数 4 { 5 if (number < 1) 6 { 7 return; 8 } 9 int* pProbabilities[2];//int指针数组 10 11 pProbabilities[0] = new int[g_MaxValue * number + 1];//多分配一个空间,0号位置不用 12 pProbabilities[1] = new int[g_MaxValue * number + 1];//多分配一个空间,0号位置不用 13 14 for (int i = 0 ; i < (g_MaxValue * number + 1) ; i++ )//数组初始化为0 15 { 16 pProbabilities[0][i] = 0 ; 17 pProbabilities[1][i] = 0 ; 18 } 19 20 int flag = 0 ;//标记数组 21 for (int i = 1 ; i <= g_MaxValue ; i++) 22 { 23 pProbabilities[flag][i] = 1 ; //取一个骰子,点数出现1到6的次数分别为1次 24 } 25 26 for (int k = 2 ; k <= number ; k++) //处理剩下的骰子 27 { 28 for (int i = 0 ; i < k ; i++) //k个骰子点数和最小是k,将小于k的次数赋值为0 29 { 30 pProbabilities[1 - flag][i] = 0 ; 31 } 32 33 for (int i = k ; i <= g_MaxValue * k ; i++) //依次处理k个骰子的所有可能点数和 34 { 35 pProbabilities[1 - flag][i] = 0 ;// 给点数和为i的出现次数赋值前先初始化为0 36 37 for (int j = 1 ;j <= i && j <= g_MaxValue ; j++)//i 表示点数和为 i,j 表示最后一个骰子可以出现的点数 38 { 39 pProbabilities[1 - flag][i] += pProbabilities[flag][i - j]; 40 //i-j 表示前 k-1 个骰子的点数和 , 此时k个骰子的点数和为 i 的次数就是当第k个骰子点数为j 时前 k-1 个骰子的点数和为 i-j 的次数。 41 } 42 } 43 flag = 1 - flag ;//调换数组 44 45 } 46 47 double total = pow((double)g_MaxValue , number) ;//可能情况的总数 48 cout<<"和\t"<<"次数\t"<<"概率"<<endl ; 49 for (int i = number ; i <= g_MaxValue * number ; i++) 50 { 51 double ratio = (double)pProbabilities[flag][i] / total ; //求概率 52 cout<<i<<"\t"<<pProbabilities[flag][i]<<"\t"<<ratio<<endl; 53 } 54 55 delete[] pProbabilities[0]; 56 delete[] pProbabilities[1]; 57 } 58 59 60 int main() 61 { 62 int number = 3 ; 63 64 PrintProbability(number); 65 getchar(); 66 return 0; 67 }
结果截图: