边看边写(n个骰子的点数)

#region n个骰子的点数
    /// <summary>
    /// 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出所有可能的值出现的概率。
    /// </summary>
    class Dice
    {
        private int g_maxValue=6;
        private int _number;
        public int number 
        {
            get { return _number; }
            set { _number = value; }
        }
        public Dice(int n)
        {
            number = n;
        }
       /// <summary>
       ///Solution1 使用递归的方式,但是时间效率不高
        /// </summary>
        public void PrintProbability()
        {
            if (number < 1)
                return;
            int maxSum = number * g_maxValue;
            List<int> pProbility = new List<int>();
            for (int i = 0; i < maxSum - number+1; i++)
                pProbility.Add(0);
            Probility(number, pProbility);
            double total = Math.Pow(g_maxValue,number);
            for (int i = 0; i < maxSum - number+1; i++)
            {
                double ratio = (double)pProbility[i] / total;
                Console.WriteLine("{0}:{1}",i+number,ratio);
            }

        }
        public void Probility(int num,List<int> pProbility)
        {
            for (int i = 1; i <= g_maxValue; i++)
            {
                Probility(num, num, i, pProbility);
            }
        }
        public void Probility(int original,int current, int sum, List<int> pProbility)
        {
            if (current == 1)
                pProbility[sum - original]++;
            else
            {
                for(int i=1;i<=g_maxValue;i++)
                    Probility(original, current - 1, i + sum, pProbility);
            }
        }
        /// <summary>
        ///Solution1 使用循环的方式,但是时间效率较高
        /// </summary>
        public void PrintProbabilitySolution2()
        {
            if (number < 1)
                return;
            List<List<int>> pProbilities = new List<List<int>>(){new List<int>(),new List<int>()};
            for (int i = 0; i < g_maxValue * number + 1; ++i)
            {
                pProbilities[0].Add(0);
                pProbilities[1].Add(0);
            }

            int flag = 0;
            for (int i = 1; i <= g_maxValue; ++i)//记录的是第一个骰子每个总数出现的次数,从1到6个点数,各出现一次。
                pProbilities[flag][i] = 1;
            for (int k = 2; k <= number; ++k)//控制k的开始,k从2开始,也就是说骰子数大于2,否则,不用计算
            {
                for (int i = 0; i < k; ++i)
                    pProbilities[1 - flag][i] = 0;
                for (int i = k; i <= g_maxValue * k; ++i)
                {
                    pProbilities[1 - flag][i] = 0;
                  //f(n)=f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)+f(n-6),均是上次循环的相差1,2,3,4,5,6的次数
                   for (int j = 1; j <= i && j <= g_maxValue; ++j)
                        pProbilities[1 - flag][i] += pProbilities[flag][i - j];
                }
                flag = 1 - flag;//flag用于切换数组
            }
            double total = Math.Pow(g_maxValue, number);
            for (int i = 0; i < g_maxValue * number+1; i++)
            {
                double ratio = (double)pProbilities[flag][i] / total;
                Console.WriteLine("{0}:{1}", i, ratio);
            }
        }
    }
    #endregion


你可能感兴趣的:(n个骰子的点数)