LightOJ-1364 Expected Cards(期望dp)

来源:互联网 发布:学生请假软件 编辑:程序博客网 时间:2024/04/30 08:26

O - Expected Cards

 LightOJ - 1364 
题解:高维期望dp,dp[i][j][k][s][q][p]表示每种牌分别有i,j,k,s张,Joker的状态分别为q,p时的期望值,用记忆化搜索一下

#include<bits/stdc++.h>using namespace std;const double eps = 1e-8;double dp[15][15][15][15][6][6];int x[10];int A, B, C, D;bool ok (int a, int b, int c, int d, int e, int f) {    x[1] = a; x[2] = b; x[3] = c; x[4] = d;    x[e]++; x[f]++;    if (x[1] < A || x[2] < B || x[3] < C || x[4] < D) return 0;    return 1;}double DP (int i, int j, int k, int s, int q, int p) {    if (ok (i, j, k, s, q, p)) return dp[i][j][k][s][q][p] = 0;    if (dp[i][j][k][s][q][p] > -eps) return dp[i][j][k][s][q][p];    double ret = 0;    int tot = i + j + k + s;    if (q) tot++;    if (p) tot++;    if (tot == 54) return 0;    if (i < 13) ret += DP (i + 1, j, k, s, q, p) * (13 - i) ;    if (j < 13) ret += DP (i, j + 1, k, s, q, p) * (13 - j) ;    if (k < 13) ret += DP (i, j, k + 1, s, q, p) * (13 - k) ;    if (s < 13) ret += DP (i, j, k, s + 1, q, p) * (13 - s) ;    //注意:当翻开的牌是Joker时,当时就要选择Joker要变成什么样的牌,并且使得翻牌期望值最低    if (q == 0)  {        double tmp = 100;        for (int qq = 1; qq <= 4; qq++)            tmp = min (tmp, DP (i, j, k, s, qq, p));        ret += tmp;    }    if (p == 0) {        double tmp = 100;        for (int pp = 1; pp <= 4; pp++)            tmp = min (tmp, DP (i, j, k, s, q, pp));        ret += tmp;    }    ret = ret / (54 - tot) + 1;    return dp[i][j][k][s][q][p] = ret;}void init() {    for (int i = 0; i <= 13; i++)        for (int j = 0; j <= 13; j++)            for (int k = 0; k <= 13; k++)                for (int s = 0; s <= 13; s++)                    for (int q = 0; q <= 4; q++)                        for (int p = 0; p <= 4; p++)                            dp[i][j][k][s][q][p] = -1.0;}int main() {    int T;    //  freopen ("in.txt", "r", stdin);    scanf ("%d", &T);    for (int cas = 1; cas <= T; cas++) {        init();        scanf ("%d%d%d%d", &A, &B, &C, &D);        int t = 0;        t += max (A - 13, 0); t += max (B - 13, 0); t += max (C - 13, 0); t += max (D - 13, 0);        if (t > 2) printf ("Case %d: -1\n", cas);        else  printf ("Case %d: %.10f\n", cas, DP (0, 0, 0, 0, 0, 0));    }    return 0;}



0 0