1 条题解
-
0
题解:老虎机期望游戏币数
题目分析
我们有一个集合 包含 个长度为 的 串,老虎机随机选择一个 作为答案串。
每次拉杆(花费 1 游戏币)会得到一个信息串 :
- 对于位置 ,有 概率 (获得真实信息)
- 有 概率 (无信息)
所有位置独立。
玩家在能唯一确定答案串时停止。对于每个可能的答案串 ,求在最优策略下的期望游戏币数。
关键观察
-
状态表示:
在获得若干次观测后,玩家会有一个"候选集" ,包含所有与目前观测一致的字符串。
当 时停止。 -
状态转移:
设当前候选集为 ,拉一次杆得到观测 (一个长度为 的串,每个位置是 ),
然后候选集会更新为 $C' = \{s \in C \mid \forall i, o_i =\ ?\ \vee\ o_i = s_i\}$。 -
概率计算:
$$\Pr(o \mid s) = \prod_{i=0}^{l-1} \begin{cases} p_i & \text{if } o_i = s_i \\ 1-p_i & \text{if } o_i =\ ? \\ 0 & \text{otherwise} \end{cases} $$
对于固定答案串 ,得到观测 的概率是: -
最优策略:
在状态 下,最优策略是选择能最小化期望额外成本的拉杆次数。
这可以用动态规划求解。
动态规划设计
设 表示当前候选集为 时,在最优策略下还需要花费的期望游戏币数(假设答案在 中)。
边界:如果 ,则 (已确定答案)。
转移:拉一次杆后,根据观测 会转移到 。
对于固定答案 ,得到观测 的概率为 ,且转移到的状态是 。
因此:
$$E[C] = 1 + \min_{\text{策略}} \mathbb{E}[\text{未来成本}] $$但"策略"在这里其实是固定的:我们只能拉杆观测,没有其他选择。所以:
$$E[C] = 1 + \sum_{s \in C} \frac{1}{|C|} \sum_o \Pr(o \mid s) \cdot E[C_o] $$这里 遍历所有 种可能的观测串(每位 )。
问题简化
注意 依赖于真正的答案在 中,但不知道是哪一个。
我们实际需要的是:对于每个 ,从初始状态 开始,假设答案就是 的期望成本 。设 表示当前候选集为 ,且真实答案为 时的期望额外成本。
则:
$$F(C, t) = 1 + \sum_o \Pr(o \mid t) \cdot F(C_o, t) $$边界:若 ,则 。
我们要求的就是 对于每个 。
算法实现
由于 ,我们可以用位集表示候选集,但 可能很大,不能直接枚举所有子集。
但注意:观测只依赖于字符串间的区别。我们可以用"区分集"的思想:
对于两个串 ,它们在第 位不同。要区分它们,需要在第 位获得真实信息(概率 )。
实际上,这是一个随机过程直到某个停止条件的问题,可以用包含-排除原理或高维DP解决。
更高效的解法
设 是 的子集,定义 为一次观测不能区分 中任意两个串的概率。
那么 中的串在观测后仍然全部在同一个候选集中的概率是:
但实际上更简单:不能区分 意味着对于每个位置 ,要么所有串在该位相同且观测为 ?,要么观测为该位的值。
经过推导(见样例解释),可以得到:
对于固定答案串 ,期望游戏币数为:
$$E_t = \sum_{T \subseteq S,\ t \in T} (-1)^{|T|-1} \frac{1}{1 - P_T} $$其中 是一次观测后 中所有串仍然无法区分的概率。
概率 的计算
中所有串无法区分,当且仅当对于每个位置 :
- 如果 中所有串在第 位相同,则观测可以是该位值或 ?
- 如果 中串在第 位有不同值,则观测必须是 ?
所以:
$$P_T = \prod_{i=0}^{l-1} \begin{cases} 1 & \text{if } T \text{ 在位置 } i \text{ 有不同值} \\ p_i + (1-p_i) = 1 & \text{实际上这里需要修正} \end{cases} $$正确公式: 设 如果 中所有串在第 位相同,否则为 0。
那么:
$$P_T = \prod_{i=0}^{l-1} \begin{cases} 1 & \text{if } b_i(T) = 0 \ (\text{有不同值,必须观测为?}) \\ 1 & \text{if } b_i(T) = 1 \ (\text{相同,观测任意}) \end{cases} \ \text{❌ 这不对} $$重新推导:
对于位置 :
- 如果 中所有串在第 位都是 ,那么观测可以是 (概率 )或 ?(概率 ),所以该位贡献因子 。
- 如果 中串在第 位有 和 ,那么观测必须是 ?(概率 ),所以贡献因子 。
因此:
$$P_T = \prod_{i=0}^{l-1} \begin{cases} 1 & \text{if } T \text{ 在位置 } i \text{ 上值都相同} \\ 1-p_i & \text{if } T \text{ 在位置 } i \text{ 上有不同值} \end{cases} $$
最终算法
- 预处理 个子集 的 (但 可能很大,不过 小,可以用位运算枚举)。
- 实际上我们不需要枚举所有 ,只需要枚举 在位置上的模式。
- 用包含-排除计算每个 的期望: 对 取模。
由于 可能达到 ,直接枚举 不可行。需要利用 小的特点,按位置集合进行DP。
复杂度优化
我们注意到 只依赖于 在每个位置上的取值情况(是否全相同)。
可以用 的DP计算所有模式的出现次数和符号和。具体步骤:
- 将每个串 用整数 表示。
- 对于每个位置子集 ,定义 为满足"在位置集 上所有串相同,在位置集 上有不同值"的 的带符号和。
- 用高维前缀和计算 。
- 则 可以表示为对 的求和。
这样复杂度为 ,在 时可行。
代码框架
#include <bits/stdc++.h> using namespace std; const int MOD = 998244353; int modpow(int a, int e) { int res = 1; while (e) { if (e & 1) res = 1LL * res * a % MOD; a = 1LL * a * a % MOD; e >>= 1; } return res; } int main() { int T; cin >> T; while (T--) { int l, n; cin >> l >> n; vector<int> p(l); for (int i = 0; i < l; i++) { int c; cin >> c; p[i] = 1LL * c * modpow(10000, MOD-2) % MOD; } vector<int> s(n); for (int i = 0; i < n; i++) { string str; cin >> str; int mask = 0; for (char ch : str) { mask = (mask << 1) | (ch - '0'); } s[i] = mask; } // 这里实现上述DP算法 // 由于代码较长,只给出框架 vector<int> E(n, 0); // 计算每个s[i]的期望值存入E[i] for (int i = 0; i < n; i++) { cout << E[i] << "\n"; } } return 0; }
总结
本题的核心是:
- 将问题建模为随机过程直到候选集大小为 1
- 利用包含-排除原理将期望表示为子集和
- 利用 小的特点,通过位运算和DP高效计算
- 注意模运算和概率的转换
- 1
信息
- ID
- 3299
- 时间
- 4000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 19
- 已通过
- 1
- 上传者