n 个骰子的点数。把n 个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S 的所有可能的值出现的概率。
ANSWER:
All the possible values includes n to 6n. All the event number is 6^n.
For n<=S<=6n, the number of events is f(S, n)
f(S,n) = f(S-6, n-1) + f(S-5, n-1) + … + f(S-1, n-1)
number of events that all dices are 1s is only 1, and thus f(k, k) = 1, f(1-6, 1) = 1, f(x, 1)=0 where x<1 or x>6, f(m, n)=0 where m<n
Can do it in DP.
using System; using System.Collections.Generic; using System.IO; using System.Diagnostics; namespace ConsoleApp { class RunClass { public static void Main() { int sum = 28; int N = 27; Stopwatch sw = new Stopwatch(); sw.Start(); int r1 = CalcBruteForce(sum, N);//too too too slow sw.Stop(); Console.WriteLine("" + r1 + ":" + sw.ElapsedMilliseconds); sw.Reset(); int r2 = CalcDP(sum, N); sw.Stop(); Console.WriteLine("" + r2 + ":" + sw.ElapsedMilliseconds); } public static int CalcDP(int sum, int n) { int[,] arr = new int[sum + 1, n + 1]; for (int j = 1; j < arr.GetLongLength(1); j++)//n for (int i = 0; i < arr.GetLongLength(0); i++)//sum { if (i <= 0) arr[i, j] = 0; else if (i > 6 * j) arr[i, j] = 0; else if (j == 1) arr[i, j] = 1; //dp else { int m = 0; for (int t = 1; t <= 6; t++) { if (i - t >= 0) m += arr[i - t, j - 1]; } arr[i, j] = m; } } return arr[sum,n]; } public static int CalcBruteForce(int sum, int n) { if (sum <= 0) return 0; if (sum == n) return 1; if (sum > 6 * n) return 0; if(n==1) return 1; int rst = CalcBruteForce(sum - 1, n - 1) + CalcBruteForce(sum - 2, n - 1) + CalcBruteForce(sum - 3, n - 1) + CalcBruteForce(sum - 4, n - 1) + CalcBruteForce(sum - 5, n - 1) + CalcBruteForce(sum - 6, n - 1); return rst; } } }