题目:
把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印s所有可能的值出现的概率。
思路:
一共有6^n种情况,点数的范围为n----6*n,只需统计出每个点数出现的次数,即可求出所有的概率。
首先分析第一个骰子可能的点数和为1到6,用数组pos1存储,当有两个骰子时,点数和为K的次数肯定为上一次点数和为K-1,K-2,...,K-6出现次数的总和。将本次计算结果保存到pos2数组中,这样一直计算到n个骰子时,pos2中的数即为每个点数和出现的次数。
假设出现的点数为K,则将其出现的次数保存到pos[K]中;由n个骰子的点数来推出n+1个骰子的点数分布时,在计算出n+1个骰子的点数分布后,需要将上面提到的pos1数组清空,并且将pos2复制到pos1,然后再将pos2清空。
时间复杂度:O(n)
空间复杂度:O(n)
下面用flag处理的比较巧妙。
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <algorithm>
#include <hash_set> //for hashtable
#include <hash_map>
#include <unordered_map>
#include <set>
#include <ctime>
using namespace std;
using namespace std;
void PrintProbability(int num)
{
if (num < 1) return;
vector<vector<int>> probabilities(2, vector<int> (num * 6 + 1, 0));
int flag = 0;
for (int i = 1; i <= 6; ++i) probabilities[flag][i] = 1;
for (int k = 2; k <= num; ++k)//k表示骰子数目
{
for (int i = 0; i < k; ++i) probabilities[1 - flag][i] = 0; //低于骰子数目的和不可能出现
for (int i = k; i <= 6 * k; i++) //i为可能出现的点数和
{
probabilities[1 - flag][i] = 0; //清0,后面要+=
for (int j = 1; j <= i&&j <= 6; ++j)
probabilities[1 - flag][i] += probabilities[flag][i - j]; //求和为K-1,K-2,...,K-6的次数和
}
flag = 1 - flag; //交换数组,避免复制数组内容
}
/*下面是打印部分*/
double total = pow(6.0, num);
for (int i = num; i <= num * 6; ++i)
cout << i << "\t" << (double)probabilities[flag][i] / total << endl;
}
int main()
{
PrintProbability(3);
return 0;
}
下面是暴力解法:
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
#define MAX 6
void Probality(int orignal, int count, int sum, int *probality)
{
if (count == 1)
{
probality[sum - orignal]++;
return;
}
for (int i = 1; i <= MAX; i++)
{
Probality(orignal, count - 1, sum + i, probality);
}
}
void PrintProbality(int n)
{
int *probality = new int[n * MAX -n + 1];
for (int i = 0; i < n * MAX-n+ 1; i++)
probality[i] = 0;
for (int i = 1; i <= MAX; i++)
{
Probality(n, n, i, probality);
}
for (int i = 0; i < n * MAX - n+1; ++i)
cout << "和为" << i + n << ":" << probality[i]/pow(6,n) << endl;
delete[] probality;
}
int main()
{
PrintProbality(20);
return 0;
}