Light OJ 1064 - Throwing Dice
题目大意:
给你n个骰子, 问点数大于等于x的概率是多少?
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; const int INF = 1e9+7; const int MAXN = 555; struct node { LL a, b;///分子,分母 bool vis; node (LL a=0,LL b=0,bool vis=false): a(a), b(b), vis(vis) {} }dp[MAXN][MAXN]; LL gcd(LL a, LL b) { return b == 0?a:gcd(b,a%b); } node DFS(int n,int x)///n个筛子掷的至少点数为x { if(x <= n) return node(1,1,true); if(dp[n][x].vis) return dp[n][x]; if(n == 0 || x > n*6) return dp[n][x] = node(0,0,true); dp[n][x] = node(0,0,true); for(int i=1; i<=6; i++) { node P = DFS(n-1, x-i); P.b *= 6; LL a = dp[n][x].a; LL b = dp[n][x].b; LL c = P.a, d = P.b; if(dp[n][x].b == 0) dp[n][x] = P; else { LL e = gcd(b,d); dp[n][x].a = a*(d/e) + c*(b/e); dp[n][x].b = b/e*d; LL k = gcd(dp[n][x].a, dp[n][x].b); dp[n][x].a /= k; dp[n][x].b /= k; } } return dp[n][x]; } int main() { int T, n, x, cas = 1; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &x); node P = DFS(n, x); printf("Case %d: ", cas ++); if(P.a == 0 || P.b == 1) printf("%lld\n", P.a); else printf("%lld/%lld\n", P.a, P.b); } return 0; }