AcWing 218. 扑克牌

f[A][B][C][D][X][Y]表示当前由A张红桃,B张黑桃,C张梅花,D张方片,且小王的状态为X,大王的状态为Y的情况的期望的最小值
此时可以通过枚举每一个变量的状态得到状态转移

#include <bits/stdc++.h>
using namespace std;
const int N = 15;
const double INF = 1e20;
int T, n, A, B, C, D;
double f[N][N][N][N][5][5];
double dp(int a, int b, int c, int d, int x, int y) 
{
    double &v = f[a][b][c][d][x][y];
    if (v >= 0) return v;
    int as = a + (x == 0) + (y == 0);
    int bs = b + (x == 1) + (y == 1);
    int cs = c + (x == 2) + (y == 2);
    int dx = d + (x == 3) + (y == 3);
    if (as >= A && bs >= B && cs >= C && ds >= D)   return v = 0;
    int sum = a + b + c + d + (x != 4) + (y != 4);
    sum = 54 - sum;
    if (sum <= 0)   return v = INF;
    v = 1;
    if (a < 13) v += (13.0 - a) / sum * dp(a + 1, b, c, d, x, y);
    if (b < 13) v += (13.0 - b) / sum * dp(a, b + 1, c, d, x, y);
    if (c < 13) v += (13.0 - c) / sum * dp(a, b, c + 1, d, x, y);
    if (d < 13) v += (13.0 - d) / sum * dp(a, b, c, d + 1, x, y);
    if (x == 4) {
        double t = INF;
        for (int i = 0; i < 4; i ++ )   t = min(t, 1.0 / sum * dp(a, b, c, d, i, y));
        v += t;
    }
    if (y == 4) {
        double t = INF;
        for (int i = 0; i < 4; i ++ )   t = min(t, 1.0 / sum * dp(a, b, c, d, x, i));
        v += t;
    }
    return v;
}
int main() {
    memset(f, -1, sizeof f);
    scanf("%d%d%d%d", &A, &B, &C, &D);
    double t = dp(0, 0, 0, 0, 4, 4);
    if (t > INF / 2)    t = -1;
    printf("%.3lf\n", t);
    return 0;
}
posted @   Angels_of_Death  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示