题目大意:
就是问投骰子n次, 得到的点数和不小于x的概率 骰子6个面点数分别为1,2,3,4,5,6,出现几率一样
大致思路:
就是一个简单的计数问题, 转台转移方程见代码注释
由于涉及到大数,为了方便写的Java
代码如下:
Result : Accepted Memory : 23824 KB Time : 296 ms
/*
* Author Gatevin
* Created Time : 2014/12/24 20:21:54
* File Name: Sora_Kasugano.java
*/
import java.util.Scanner;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Map;
import java.util.HashMap;
import java.util.Queue;
import java.util.LinkedList;
import java.io.FileOutputStream;
/*
* 很简单的一个dp计数问题
* 如果用dp[i][j]表示在投掷i次之后点数和为j的方案数
* 那么dp[i][j] = ∑dp[i - 1][j - k] (1 <= k <= min(6, j))
* 初始dp[0][0]这样得到所有的投掷n次点数为m的方案数
* 直接求和即可得到满足题意的方案, 约分一下就行了
*/
//submit前写的"public class Sora_Kasugano" CompilationError了一发..
public class Main{
public static void main(String args[]){
int t, n, x;
BigInteger dp[][] = new BigInteger[26][160];
for(int i = 1; i <= 150; i++) dp[0][i] = BigInteger.ZERO;
dp[0][0] = BigInteger.ONE;
for(int i = 1; i <= 25; i++)
{
for(int j = 0; j < i; j++) dp[i][j] = BigInteger.ZERO;
for(int j = i; j <= 6*i; j++)
{
dp[i][j] = BigInteger.ZERO;
for(int k = 1; k <= 6; k++)
if(j >= k)
dp[i][j] = dp[i][j].add(dp[i - 1][j - k]);
}
for(int j = 6*i + 1; j <= 150; j++) dp[i][j] = BigInteger.ZERO;
}
Scanner cin = new Scanner(System.in);
t = cin.nextInt();
for(int cas = 1; cas <= t; cas++)
{
n = cin.nextInt();
x = cin.nextInt();
BigInteger dem = BigInteger.valueOf(6).pow(n);
BigInteger num = BigInteger.ZERO;
for(int i = x; i <= 6*n; i++)
num = num.add(dp[n][i]);
BigInteger gcd = dem.gcd(num);
dem = dem.divide(gcd);
num = num.divide(gcd);
if(dem.compareTo(BigInteger.ONE) != 0)
System.out.println("Case " + cas + ": " + num + "/" + dem);
else
System.out.println("Case " + cas + ": " + num);
}
}
}