uva 10759 - Dice Throwing(dp)

题目链接:uva 10759 - Dice Throwing


题目大意:给出n和x,计算在丢n个色子,出现的点数大于等于x的概率,要求分式最简。


解题思路:一开始方向想错了,一直在枚举num[i][j], i表示i个色子丢出的点数小于x的情况,一直找不到状态转移方程,推出来几个都是错的,算了一下午;后来发现num[i][j] 与num[i][j + 1]中间的增长个数与用i个色子丢出的点数为j的情况有关,然而求用i个色子丢出点数的情况则是非常好求的:num[i][j]  = ∑(j + 1 ≤ k ≤ j + 6)num[i][k].

然后就可以进一步的去求丢出i个色子丢出的点数小于x的情况。


#include <stdio.h>
#include <string.h>

int n, x;
long long num[30][160], sum[30];

void init() {
	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];
		}
	}
}

long long  gcd(long long a, long long b) {
	return b == 0 ? a : gcd (b, a % b);
}

int main () {
	init();
	long long a, b, d;
	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;
}


你可能感兴趣的:(uva 10759 - Dice Throwing(dp))