返回题库

争夺王牌

Race to Ace

专题
Probability / 概率
难度
L5

题目详情

在看到第一张 A 之前,你需要从 52 张牌中抽出多少张牌?

What is the expected number of cards you need to draw from a 52-card deck before you see the first ace?

解析

假设你有以下设置:

___A1___A2___A3___A4___\begin{equation*} \_\_\_ A_1 \_\_\_ A_2 \_\_\_ A_3 \_\_\_ A_4 \_\_\_ \end{equation*}

其中 AnA_n 代表 nthnth Ace,间隙代表它们之间的牌。

4848 卡可放入 55 间隙中,因此每个间隙的预期卡数为 485\frac{48}5。从第一个间隙中挑选出所有牌后,你挑选的下一张牌将是 A,因此在获得 A 之前我们挑选的牌的预期数量为

485+1=10.6\begin{equation*} \frac{48}5+1 = \boxed{10.6} \end{equation*}
import random
from typing import Tuple
from itertools import product

suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']

class Deck:
    def __init__(self) -> None:
        """Initialize a deck of cards"""
        self.cards = [(rank, suit) for rank, suit in product(ranks, suits)]

    def shuffle(self) -> None:
        """Shuffle a deck of cards"""
        self.cards = random.sample(self.cards, 52)

    def draw(self) -> Tuple[str, str]:
        """Draw a card from the deck"""
        return self.cards.pop()

    def isEmpty(self) -> bool:
        """Check if the deck has cards"""
        return self.cards == []

def simulation() -> int:
    deck = Deck()
    deck.shuffle()

    cards_drawn = 0

    # Keep drawing until we find an ace
    while not deck.isEmpty():
        suit, rank = deck.draw()
        cards_drawn += 1

        if suit == "A":
            return cards_drawn

    return cards_drawn

cards_needed = [simulation() for _ in range(10_000)]

# Get the expected number of cards until we draw our first ace
print(sum(cards_needed) / len(cards_needed))

Original Explanation

Imagine you have the following setup:

___A1___A2___A3___A4___\begin{equation*} \_\_\_ A_1 \_\_\_ A_2 \_\_\_ A_3 \_\_\_ A_4 \_\_\_ \end{equation*}

Where AnA_n represents the nthnth Ace and the gaps represent the cards in between them.

There are 4848 cards to place into the 55 gaps, thus the expected number of cards per gap is 485\frac{48}5. After picking all the cards from the first gap, the next card you pick would be an ace so the expected number of cards we pick until we get an ace is

485+1=10.6\begin{equation*} \frac{48}5+1 = \boxed{10.6} \end{equation*}
import random
from typing import Tuple
from itertools import product

suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']

class Deck:
    def __init__(self) -> None:
        """Initialize a deck of cards"""
        self.cards = [(rank, suit) for rank, suit in product(ranks, suits)]

    def shuffle(self) -> None:
        """Shuffle a deck of cards"""
        self.cards = random.sample(self.cards, 52)

    def draw(self) -> Tuple[str, str]:
        """Draw a card from the deck"""
        return self.cards.pop()

    def isEmpty(self) -> bool:
        """Check if the deck has cards"""
        return self.cards == []

def simulation() -> int:
    deck = Deck()
    deck.shuffle()

    cards_drawn = 0

    # Keep drawing until we find an ace
    while not deck.isEmpty():
        suit, rank = deck.draw()
        cards_drawn += 1

        if suit == "A":
            return cards_drawn

    return cards_drawn

cards_needed = [simulation() for _ in range(10_000)]

# Get the expected number of cards until we draw our first ace
print(sum(cards_needed) / len(cards_needed))