news 2026/5/14 18:29:17

UVa 10835 Playing with Coins

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 10835 Playing with Coins

问题描述

Jack \texttt{Jack}JackJill \texttt{Jill}Jill对抛硬币生成的序列模式感兴趣。给定抛硬币次数N NNK KK个禁止的子模式,我们需要计算不包含任何禁止子模式的序列的概率。

输入

  • 每个测试用例包含两个整数N NNK KK1 ≤ N ≤ 50 1 \leq N \leq 501N500 ≤ K ≤ 50 0 \leq K \leq 500K50
  • 接下来K KK行,每行是一个由字符HT组成的子模式
  • 所有子模式长度相同,且长度不超过10 1010
  • 输入以N = K = 0 N = K = 0N=K=0结束

输出

  • 对于每个测试用例,输出概率的最简分数形式a / b a/ba/b,如果概率为0 00则输出0

解题思路

1. 问题转化

这是一个典型的字符串模式匹配问题。我们需要统计长度为N NNH/T序列中,不包含任何给定子模式的序列数量。

总序列数为2 N 2^N2N,因此:
概率 = 安全序列数 2 N \text{概率} = \frac{\text{安全序列数}}{2^N}概率=2N安全序列数

2. 关键观察

  1. 子模式长度固定:所有禁止子模式长度相同,设为M MMM ≤ 10 M \leq 10M10
  2. 状态表示:对于模式匹配问题,我们只需要关心序列的最后M MM个字符,因为更早的字符不会影响是否匹配长度为M MM的子模式
  3. 位掩码表示:可以用二进制位表示序列:
    • H→ 1
    • T→ 0
    • 长度为M MM的子模式可以表示为一个M MM位二进制数

3. 算法设计

状态定义

d p [ length ] [ mask ] dp[\texttt{length}][\texttt{mask}]dp[length][mask]表示:

  • 当前序列长度为length \texttt{length}length
  • 序列的最后M MM个字符(不足M MM位时用前导零补齐)的位掩码为mask \texttt{mask}mask
  • 值为满足以上条件且不包含任何禁止子模式的序列数量
状态转移

从当前状态( length , mask ) (\texttt{length}, \texttt{mask})(length,mask)可以:

  1. 添加一个H(二进制 1)
  2. 添加一个T(二进制 0)

新的掩码计算方式:
newMask = ( ( mask ≪ 1 ) & ( ( 1 ≪ M ) − 1 ) ) ∣ bit \texttt{newMask} = ((\texttt{mask} \ll 1) \& ((1 \ll M) - 1)) \mid \texttt{bit}newMask=((mask1)&((1M)1))bit
其中:

  • << 1表示左移一位,相当于去掉最旧的字符
  • & ((1 << M) - 1)确保掩码保持在M MM
  • | bit添加新字符(0 001 11
禁止模式检查

只有当序列长度≥ M − 1 \geq M-1M1时,才需要检查新的掩码是否在禁止集合中:

  • 如果newMask \texttt{newMask}newMask在禁止集合中,则跳过该转移
  • 否则,继续递归
边界条件
  • length = N \texttt{length} = Nlength=N时,找到一个安全序列,返回1 11
  • 使用记忆化搜索避免重复计算

4. 特殊情况处理

  1. K = 0 K = 0K=0:没有禁止模式,所有2 N 2^N2N个序列都安全,概率为1 11
  2. M > N M > NM>N:禁止模式长度大于序列长度,不可能出现该模式,所有序列都安全,概率为1 11
  3. 否则:使用动态规划计算安全序列数

5. 概率计算

设安全序列数为safe \texttt{safe}safe,总序列数为2 N 2^N2N,则:
概率 = safe 2 N \text{概率} = \frac{\texttt{safe}}{2^N}概率=2Nsafe
需要化简为最简分数,使用gcd ⁡ \gcdgcd函数求最大公约数。

算法复杂度分析

  • 状态数O ( N × 2 M ) O(N \times 2^M)O(N×2M),其中M ≤ 10 M \leq 10M10
  • 每个状态转移O ( 1 ) O(1)O(1)
  • 总复杂度O ( N × 2 M ) O(N \times 2^M)O(N×2M),对于N ≤ 50 N \leq 50N50完全可行
  • 空间复杂度O ( N × 2 M ) O(N \times 2^M)O(N×2M)

代码实现

// Playing with Coins// UVa ID: 10835// Verdict: Accepted// Submission Date: 2025-12-22// UVa Run Time: 0.020s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;set<int>forbidden;// 存储禁止模式的位掩码intN,K,M;// N:总长度, K:禁止模式数, M:模式长度longlongdp[64][1024];// dp[i][j]: 长度i,最后M位的掩码为j// 记忆化搜索longlongdfs(intlength,intmask){if(length>=N)return1LL;// 找到一个安全序列if(~dp[length][mask])returndp[length][mask];// 记忆化longlong&r=dp[length][mask];r=0;// 尝试添加 H(1) 或 T(0)for(inti=0;i<=1;i++){intnextMask=(((mask<<1)&((1<<M)-1)))|i;// 只有长度足够时才检查禁止模式if(length<M-1||!forbidden.count(nextMask))r+=dfs(length+1,nextMask);}returnr;}intmain(){intcaseNo=1;while(cin>>N>>K,N){cout<<"Case "<<caseNo++<<": ";forbidden.clear();// 读入禁止模式并转换为位掩码for(inti=0;i<K;i++){string pattern;cin>>pattern;M=pattern.length();intmask=0;for(autop:pattern)mask=(mask<<1)|(p=='H'?1:0);forbidden.insert(mask);}// 特殊情况处理:没有禁止模式或模式长度大于序列长度if(K==0||M>N){cout<<"1/1\n";continue;}// 动态规划计算安全序列数memset(dp,-1,sizeofdp);longlongsafe=dfs(0,0);// 输出结果if(safe==0)cout<<"0\n";else{longlongtotal=1LL<<N;longlongg=__gcd(safe,total);cout<<safe/g<<'/'<<total/g<<'\n';}}return0;}

样例解析

样例输入

3 1 HH 3 1 HT 3 2 T H 0 0

样例输出

Case 1: 5/8 Case 2: 1/2 Case 3: 0

解释

Case 1 \texttt{Case 1}Case 1

  • N = 3 N = 3N=3,禁止模式:HH(二进制 11)
  • 包含HH的序列:HHH,HHT,THH(3个)
  • 安全序列:8 − 3 = 5 8 - 3 = 583=5
  • 概率:5 / 8 5/85/8

Case 2 \texttt{Case 2}Case 2

  • 禁止模式:HT(二进制 10)
  • 包含HT的序列:HHT,HTH,HTT,THT(4个)
  • 安全序列:4 44
  • 概率:4 / 8 = 1 / 2 4/8 = 1/24/8=1/2

Case 3 \texttt{Case 3}Case 3

  • 禁止模式:T(0)和H(1)
  • 所有序列都至少包含一个TH
  • 安全序列:0 00
  • 概率:0 00

总结

本题通过位掩码 + 动态规划(记忆化搜索)的方法,高效地解决了模式匹配计数问题。关键点在于:

  1. 用二进制位表示字符序列,简化操作
  2. 只需维护最后M MM个字符的状态
  3. 记忆化搜索避免重复计算
  4. 特殊情况的预处理
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 22:47:17

从合规到实战:企业安全建设的合规检查落地指南与风险规避策略

一、安全合规检查的核心价值&#xff1a;不止于“满足监管”&#xff0c;更是“安全筑基” 在数字化转型加速的当下&#xff0c;企业安全合规检查早已脱离“应付检查”的浅层认知&#xff0c;成为构建企业纵深防御体系的核心抓手。对于企业而言&#xff0c;合规检查的价值体现在…

作者头像 李华
网站建设 2026/5/9 5:36:52

LangFlow在AIGC领域的10种创新应用场景

LangFlow在AIGC领域的10种创新应用场景 在生成式AI&#xff08;AIGC&#xff09;迅速渗透各行各业的今天&#xff0c;一个核心矛盾日益凸显&#xff1a;大语言模型&#xff08;LLM&#xff09;的能力越来越强&#xff0c;但将其落地为可用产品的门槛却依然高得令人望而却步。开…

作者头像 李华
网站建设 2026/5/12 10:39:40

LangFlow日志记录功能配置说明

LangFlow日志记录功能配置说明 在构建复杂的AI工作流时&#xff0c;一个常见的挑战是&#xff1a;当流程运行异常或性能不佳时&#xff0c;我们往往只能看到“前端无输出”或“响应缓慢”这类模糊现象。尤其是在使用可视化工具如 LangFlow 进行快速原型开发的过程中&#xff0c…

作者头像 李华
网站建设 2026/5/7 4:20:17

SGLang AI 金融 π 对(杭州站)回顾:大模型推理的工程实践全景

12 月 20 日&#xff0c;SGLang AI 金融 π 对&#xff08;杭州站&#xff09;在杭州紫金港美居酒店成功举办。本次 Meetup 由 SGLang 与 AtomGit 社区联合发起&#xff0c;聚焦大模型在金融与复杂业务场景下的推理效率问题&#xff0c;吸引了大量来自 AI Infra、推理系统、金融…

作者头像 李华
网站建设 2026/5/4 9:09:24

Solana钓鱼攻击中Owner权限滥用机制与防御体系研究

摘要近年来&#xff0c;随着高性能区块链平台Solana生态的快速扩张&#xff0c;其独特的账户与权限模型在提升交易效率的同时&#xff0c;也引入了新型安全风险。2024年末至2025年初&#xff0c;多起针对Solana用户的钓鱼攻击事件造成数百万美元资产损失&#xff0c;其核心攻击…

作者头像 李华
网站建设 2026/5/9 12:45:27

能源管理系统(开源):打造智能高效的能源管控新模式

温馨提示&#xff1a;文末有资源获取方式~能源系统|能源系统源码|企业能源系统|企业能源系统源码|能源监测系统一、Java 与能源管理系统的邂逅​能源管理系统的核心使命在于实现能源的精细化管控。它通过实时收集各类能源数据&#xff0c;如电力、燃气、水、热能等的消耗情况&a…

作者头像 李华