【笔试】52、N个骰子的点数

/****************************************************************************************
 *题目: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);
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值