/****************************************************************************************
*题目:N个骰子的点数
* 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
*时间:2015年10月5日11:37:41
*文件:DicesProbability.java
*作者:cutter_point
****************************************************************************************/
package bishi.Offer50.y2015.m10.d06;
import org.junit.Test;
public class DicesProbability
{
private int g_maxvalue = 6; //骰子出现的最大值
public void printProbability2(int number)
{
if(number < 1)
return;
//设定两个数组保存上一次的数据,动态规划!!!,设定一个二维数组把
int pProbabilities[][] = new int[2][g_maxvalue * number + 1];
//初始化为0
for(int i = 0; i < pProbabilities.clone().length; ++i)
{
pProbabilities[0][i] = 0;pProbabilities[1][i] = 0;
}//for
//设定一个标志,确定那个是上一个循环的数据
int flag = 0;
//设定flag = 0的开始数据
for(int i = 1; i <= g_maxvalue; ++i)
{
pProbabilities[flag][i] = 1;
}//for
//然后我们不断添加骰子个数
for(int k = 2; k <= number; ++k)
{
for(int i = 0; i < k; ++i) //去掉添加骰子导致的一些数据这个是根据骰子个数删除一些数据
{
//比如:
//一个骰子的时候有1
//两个骰子的时候没有1
pProbabilities[1 - flag][i] = 0;
}//for
//计算1-flag中的数据,这里注意:当我们第一个骰子投出数字n的次数是n的时候,我们加一个骰子,发现数字是n-6,n-5,n-4,n-3,n-2,n-1的和
for(int i = k; i <= g_maxvalue * k; ++i)
{
pProbabilities[1-flag][i] = 0;//先修改为0
for(int j = 1; j <= g_maxvalue && j <= i; ++j) //后面的j<=i是为了避免i - j < 0,避免越界
{
pProbabilities[1-flag][i] += pProbabilities[flag][i - j];
}//for
}//for
//修改标志
flag = 1 - flag;
}//for
//计算概率
double total = (double)Math.pow(g_maxvalue, number);
for(int i = number; i < g_maxvalue * number + 1; ++i)
{
double radio = (double)pProbabilities[flag][i] / total;
System.out.println(i + "\t的概率是:" + radio);
}//for
}
/**
* @param original 我们开始有几个骰子
* @param current 我们当前遍历第几个(我们是倒着来的,开始是第6号)
* @param sum 我们骰子的累积和
* @param pProbabilities 我们出现次数的数组
*/
private void probability(int original, int current, int sum, int pProbabilities[])
{
if(current == 1)
{
//这个表示遍历到了最后一个骰子
pProbabilities[sum - original]++;
}//if
else
{
//如果不是最后一个那么接下来current这个骰子有很多种可能
for(int i = 1; i <= g_maxvalue; ++i)
{
probability(original, current - 1, sum + i, pProbabilities);
}
}//else
}
/**
* 统计所有可能会出现的数据的次数
* @param number
* @param pProbabilities
*/
private void probability(int number, int pProbabilities[])
{
//第一个骰子可能出现1到6的可能
for(int i = 1; i <= g_maxvalue; ++i)
{
probability(number, number, i, pProbabilities);
}//for
}
public void printProbability(int number)
{
if(number < 1)
return;
//number和骰子可能出现的最大的值
int maxSum = number * g_maxvalue;
int pProbabilities[] = new int[maxSum - number + 1]; //所有出现的可能
for(int i = number; i <= maxSum; ++i)
{
pProbabilities[i - number] = 0; //各个点数出现的几率
}//for
//求所有出现的次数
probability(number, pProbabilities);
//接下来求概率,这个是分母,6的number次方
int total = (int) Math.pow((double)g_maxvalue, number);
for(int i = number; i <= maxSum; ++i)
{
double radio = (double)pProbabilities[i - number] / total;
System.out.println(i + "\t的概率是:" + radio);
}//for
}
@Test
public void test()
{
DicesProbability d = new DicesProbability();
d.printProbability(6);
System.out.println("######################################################");
d.printProbability2(6);
}
}
【笔试】52、N个骰子的点数
最新推荐文章于 2022-01-18 23:12:10 发布