题意:
给出n和x,计算丢n个骰子,点数和大于等于x的概率,用分数表示;
思路:
sum[i]表示投i个骰子一共有几种情况;
num[i][j]表示投j个骰子,出现小于j的情况有几种;
那么我们可以知道
num[i][j]如果在多投一次;
如果投出1;
那么就可以得出num[i+1][j+1] += num[i][j];(因为所有num[i][j]的情况再投一次1,都会是num[i+1][j+1]的情况);
同理num[i+1][j+2]一直到num[i+1][j+6]都可以加一遍;
同时num[i][j] += num[i][j - 1]因为就算不投筛子,如过投i个骰子小于等于j,那么一定小于等于比j大的数,要不停累加;
最后算出我们要求的情况有几种,除以总的情况数;用gcd消成互质就行了;
AC:
#include <stdio.h>
#include <string.h>
#define ll long long
int n, x;
ll num[30][160], sum[30];
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd (b, a % b);
}
int main () {
ll a, b, d;
memset(num, 0, sizeof(num));
for (int i = 1; i <= 6; i++)
num[1][i] = 1;
sum[0] = 1;
for (int i = 1; i <= 24; i++) {
sum[i] = sum[i - 1] * 6;
for (int j = 1; j <= 150; j++) {
for (int k = 1; k <= 6; k++)
num[i + 1][j + k] += num[i][j];
num[i][j] += num[i][j - 1];
}
}
while (scanf("%d%d", &n, &x), n || x) {
x--;
if (sum[n] == num[n][x]) printf("0\n");
else {
d = gcd(sum[n] - num[n][x], sum[n]);
a = (sum[n] - num[n][x]) / d;
b = sum[n] / d;
if (b == 1) printf("1\n");
else
printf("%lld/%lld\n", a, b);
}
}
return 0;
}