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;
}
}
}