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;
}

 

posted @ 2015-10-29 18:26  向前走丶不回首  阅读(183)  评论(0编辑  收藏  举报