1 条题解
-
0
题目分析
本题是一个简化版“憋七”游戏的博弈问题。Alice 和 Bob 轮流在四条花色链上扩展,无法行动的一方判负。需要求出双方最优策略下的游戏结果。
算法思路
核心思想:状态压缩 + 记忆化搜索
关键观察:
- 四条花色(S, H, C, D)相互独立
- 每条花色链从 7 开始向两侧扩展
- 游戏状态可由每条链的左右端点完全描述
状态表示
1. 状态结构
struct state { int l[4], r[4]; // 每条链的左右端点 };l[i]:花色 i 当前最左端的点数r[i]:花色 i 当前最右端的点数- 初始时所有链为
(0,0),黑桃链为(7,7)
2. 状态哈希
u64 hsh(state s) { u64 h = 0; for (int i = 0; i < 4; i++) { h = h * B + s.l[i]; h = h * B + s.r[i]; } return h; }使用多项式哈希将状态映射到
u64,便于存储。
博弈搜索
1. 搜索函数定义
int dfs(int cur, state s)cur:当前玩家(0=Bob, 1=Alice)s:当前游戏状态- 返回值:0-当前玩家必败,1-平局,2-当前玩家必胜
2. 终止条件
bool fle = true; for (int i = 0; i < 4; i++) { if (s.l[i] != 1 || s.r[i] != 13) fle = false; } if (fle) return m[h] = 1; // 所有链完成,平局3. 行动枚举
对于每条花色链:
情况1:链未开始(
l[i] == 0 && r[i] == 0)if (a[i][7] != cur) { // 当前玩家没有该花色的7 s.l[i] = s.r[i] = 7; int r = dfs(cur ^ 1, s); // 更新最优策略 s.l[i] = s.r[i] = 0; }情况2:链已开始,向两侧扩展
// 向左扩展 if (s.l[i] > 1 && a[i][s.l[i] - 1] != cur) { s.l[i]--; int r = dfs(cur ^ 1, s); // 更新最优策略 s.l[i]++; } // 向右扩展 if (s.r[i] < 13 && a[i][s.r[i] + 1] != cur) { s.r[i]++; int r = dfs(cur ^ 1, s); // 更新最优策略 s.r[i]--; }4. 胜负判断逻辑
int cs = 0; // 0-必败, 1-平局, 2-必胜 for (所有可能行动) { int r = dfs(对手, 新状态); if (r == 0) cs = 2; // 存在让对手必败的行动 else if (r == 1 && !cs) cs = 1; // 存在平局行动 } return m[h] = cs;
算法流程
步骤1:输入处理
for (int i = 1; i <= 26; i++) { scanf("%1s", buf); a[get(buf[0])][rd()] = 1; // 标记Alice拥有的牌 }步骤2:初始状态设置
state st = {}; st.l[0] = st.r[0] = 7; // 黑桃7已打出 int r = dfs(a[0][7], st); // 黑桃7的拥有者先手步骤3:结果转换
根据黑桃7的归属和搜索结果的组合:
黑桃7归属 搜索结果 最终结果 Alice 2 (必胜) Alice 1 (平局) Draw 0 (必败) Bob Bob 2 (必胜) 1 (平局) Draw 0 (必败) Alice
复杂度分析
状态空间
- 每条链的状态:左端点 0-7,右端点 7-13
- 总状态数:约 $8 \times 7 \times 8 \times 7 \times 8 \times 7 \times 8 \times 7 \approx 10^7$ 量级
- 实际可达状态远少于理论上限
时间复杂度
- 每个状态最多 16 种行动(4条链 × 4个方向)
- 使用哈希表记忆化,避免重复计算
- 实际运行可接受
算法优势
- 状态压缩合理:仅存储端点信息,避免记录具体出牌序列
- 记忆化高效:使用
gp_hash_table快速查询 - 博弈分析准确:标准的必胜/必败态传播
- 代码简洁:逻辑清晰,易于理解
样例验证
样例1
输入:Alice 的 26 张牌 搜索过程发现 Bob 有必胜策略 → 输出
Bob样例2
双方手牌对称,最终平局 → 输出
Draw样例3
Alice 手牌优势,存在必胜策略 → 输出
Alice该算法通过状态空间搜索和博弈论分析,准确解决了这一复杂的卡牌博弈问题。
- 1
信息
- ID
- 4665
- 时间
- 5000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者