剑指offer-n个骰子的点数
小易参加了一个骰子游戏,这个游戏需要同时投掷n个骰子,每个骰子都是一个印有数字1~6的均匀正方体。小易同时投掷出这n个骰子,如果这n个骰子向上面的数字之和大于等于x,小易就会获得游戏奖励。小易想让你帮他算算他获得奖励的概率有多大。
输入包括两个正整数n和x(1 ≤ n < 25, 1 ≤ x < 150),分别表示骰子的个数和可以获得奖励的最小数字和。
输出小易可以获得奖励的概率。如果概率为1,输出1,如果概率为0,输出0,其他以最简分数(x/y)的形式输出。
public class Main { public static void main(String[] arg) throws IOException { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int x = sc.nextInt(); int maxVal = 6; long[][] count = new long[2][maxVal*n+1];//int 会越界 int flag =0; for(int i=1;i<=maxVal;i++){//第一个骰子 count[flag][i]=1; } for(int k=2;k<=n;k++){//第k个筛子 for(int i=0;i<k;i++){//第k最小点为k count[1-flag][i] = 0; } for(int i=k;i<=maxVal*k;i++){ count[1-flag][i] =0; for(int j=1;j<=i&&j<=maxVal;j++){ count[1-flag][i] += count[flag][i-j]; } } flag =1-flag; } long total = (long)Math.pow(maxVal,n); long re = 0; for(int i=x;i<=maxVal*n;i++){ re += count[flag][i]; } long g =gcd(total,re); if(re==0){ System.out.println(0); } else if(re ==total){ System.out.println(1); } else{ System.out.println(re/g+"/"+total/g); } } public static long gcd(long a,long b){ return b==0?a:gcd(b,a%b); } }