1 条题解

  • 0
    @ 2026-5-17 19:59:54

    题意

    nn 种花色,每种花色有 1313 张牌(点数 2210JQKA10,J,Q,K,A)。
    皇家同花顺:10JQKA10,J,Q,K,A 且花色相同。
    初始随机抽 55 张牌,之后每轮:

    • 若手牌有皇家同花顺,获胜;
    • 若牌堆空,失败;
    • 否则,可弃掉任意手牌,然后抽牌至手牌 55 张或牌堆空。
      求最小期望获胜轮数(获胜那轮不计入)。

    关键转化

    • 只有 10JQKA10,J,Q,K,A55 张关键牌对获胜有用,其余牌无用。
    • 每轮我们可以弃掉无用牌,所以手牌中永远只保留关键牌(且不会保留重复的关键牌,因为弃掉后抽新的)。
    • 因此,游戏等价于:从 13n13n 张牌中(包含 5n5n 张关键牌和 8n8n 张无用牌)每次抽一张,如果抽到未集齐的关键牌则保留,否则丢弃。当集齐某花色的全部 55 张关键牌时获胜。求期望抽牌次数。

    状态表示

    总关键牌数 M=5nM = 5n
    用一个 MM 位的二进制掩码 maskmask 表示已收集的关键牌集合。
    ii0i<M0 \le i < M)对应第 i/5\lfloor i/5 \rfloor 种花色的第 imod5i \bmod 5 张关键牌(点数顺序固定为 10,J,Q,K,A10,J,Q,K,A)。
    定义 dp[mask]dp[mask] 为当前已收集 maskmask 时,还需多少步才能获胜的期望。


    边界条件

    如果 maskmask 包含某花色的全部 55 张关键牌,即存在 suitsuit 使得 maskmask[suit5,suit5+4][suit \cdot 5, suit \cdot 5 + 4] 这些位上全为 11,则已获胜:

    dp[mask]=0dp[mask] = 0

    转移方程

    设:

    • cnt=popcount(mask)cnt = \text{popcount}(mask):已收集的关键牌数量
    • R=13ncntR = 13n - cnt:剩余牌数(已抽走的 cntcnt 张关键牌已移除,其余牌还在)
    • missing=Mcnt\text{missing} = M - cnt:未收集的关键牌数量

    下一张抽牌:

    • 抽到未收集关键牌的概率 p=missingRp = \frac{\text{missing}}{R}
    • 抽到已收集关键牌或无用牌的概率 1p1-p

    设 $E_{next} = \frac{1}{\text{missing}} \sum_{i \notin mask} dp[mask \cup \{i\}]$ 为抽到未收集关键牌时的期望后继值。

    由全期望公式:

    $$dp[mask] = 1 + p \cdot E_{next} + (1-p) \cdot dp[mask] $$

    移项:

    pdp[mask]=1+pEnextp \cdot dp[mask] = 1 + p \cdot E_{next} dp[mask]=1p+Enextdp[mask] = \frac{1}{p} + E_{next}

    由于 p=missingRp = \frac{\text{missing}}{R},所以:

    dp[mask]=Rmissing+Enextdp[mask] = \frac{R}{\text{missing}} + E_{next}

    算法步骤

    11. 初始化所有 dp[mask]=0dp[mask] = 0vis[mask]=falsevis[mask] = \text{false}22. 递归计算 dp[mask]dp[mask]

    • maskmask 包含某花色的 55 张牌,返回 00
    • 计算 cnt=popcount(mask)cnt = \text{popcount}(mask)R=13ncntR = 13n - cntmissing=5ncnt\text{missing} = 5n - cnt
    • 计算 $E_{next} = \frac{1}{\text{missing}} \sum_{i \notin mask} dp[mask \cup \{i\}]$。
    • 返回 dp[mask]=Rmissing+Enextdp[mask] = \frac{R}{\text{missing}} + E_{next}33. 答案 =dp[0]= dp[0]

    复杂度

    状态数 25n2^{5n}n4n \le 4 时最大 220=1,048,5762^{20} = 1,048,576,可接受。
    每个状态遍历 missing20\text{missing} \le 20 个后继,总复杂度 O(25nn)O(2^{5n} \cdot n)


    完整代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    double dp[1 << 20];
    bool vis[1 << 20];
    
    bool hasRoyal(int mask) {
        for (int suit = 0; suit < n; suit++) {
            int royalMask = 0;
            for (int rank = 0; rank < 5; rank++) {
                royalMask |= (1 << (suit * 5 + rank));
            }
            if ((mask & royalMask) == royalMask) return true;
        }
        return false;
    }
    
    double dfs(int mask) {
        if (vis[mask]) return dp[mask];
        vis[mask] = true;
        if (hasRoyal(mask)) return dp[mask] = 0;
        
        int cnt = __builtin_popcount(mask);
        int total = 13 * n;
        int remain = total - cnt;
        int missing = 5 * n - cnt;
        
        double sumNext = 0;
        for (int i = 0; i < 5 * n; i++) {
            if (!(mask >> i & 1)) {
                sumNext += dfs(mask | (1 << i));
            }
        }
        double E_next = sumNext / missing;
        dp[mask] = (double)remain / missing + E_next;
        return dp[mask];
    }
    
    int main() {
        cin >> n;
        double ans = dfs(0);
        cout << fixed << setprecision(9) << ans << endl;
        return 0;
    }
    

    示例验证

    输入 11,输出约 3.5982905983.598290598
    输入 22,输出约 8.0671713098.067171309
    与题目样例一致。


    总结

    • 问题简化为收集特定 5n5n 张关键牌,且必须集齐同一花色的 55
    • 用状态压缩 DPDP 计算期望步数。
    • 转移公式:$dp[mask] = \frac{\text{剩余牌数}}{\text{未收集关键牌数}} + \text{后继期望的平均}$。
    • 1

    信息

    ID
    7188
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    3
    已通过
    1
    上传者