lightoj - 1064 - Throwing Dice - dp / 概率dp

来源:互联网 发布:淘宝重复铺货处罚 编辑:程序博客网 时间:2024/05/16 06:05

题意:有n个骰子,求他们的和至少为x的概率。

题解:用dp统计所有情况,设dp[i][j]为到第i个骰子时,和为j的情况有多少种,则转移为dp[i][j] = sum(dp[i][j-k]),注意边界。而扔n个骰子共有6^n种情况,所以概率为sum(dp[n-1][j], j大于等于x) / 6^n 。


#include <bits/stdc++.h>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define ll long long#define SZ(x) ((int)(x).size()) #define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i) #define REP(i,a,n) for ( int i=a; i<int(n); i++ )#define FOR(i,a,n) for ( int i=n-1; i>= int(a);i-- )#define lson rt<<1, L, m#define rson rt<<1|1, m, Rtypedef pair<int, int> pii;typedef pair<ll, ll> pll;#define mp(x, y) make_pair(x, y)#define pb(x) push_back(x)#define fi first#define se second#define CLR(a, b) memset(a, b, sizeof(a))#define Min(a, b) a = min(a, b)#define Max(a, b) a = max(a, b)const int maxn = 200;int T;int kase;int n, x;ll dp[30][maxn];ll pw[25];void ini(){    REP(j, 1, 7) dp[0][j] = 1;    REP(i, 1, 30){        REP(j, i + 1, i + 6){            REP(k, 1, j - i + 1){                dp[i][j] += dp[i-1][j-k];            }        }        REP(j, i + 6, maxn){            REP(k, 1, 7){                dp[i][j] += dp[i-1][j-k];            }        }    }    pw[0] = 1;    REP(i, 1, 25) pw[i] = pw[i-1] * 6;}int main(){#ifdef ac    freopen("in.txt","r",stdin);#endif    //freopen("out.txt","w",stdout);        ini();    scanf("%d", &T);    while(T--){        scanf("%d%d", &n, &x);        ll res = 0;        REP(j, x, maxn){            res += dp[n-1][j];        }        ll t = __gcd(res, pw[n]);        printf("Case %d: ", ++ kase);        if(pw[n] / t == 1) printf("%lld\n", res / t);        else printf("%lld/%lld\n", res / t, pw[n] / t);    }    return 0;}


0 0
原创粉丝点击