1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| \section{错误六:答案计算缺少 $+\infty$ 守卫}
\subsection*{错误代码} \begin{minted}{cpp} ll lans = INF; for (int num1 = 0; num1 < 2; ++num1) { if (d[num1][1] == INF) continue; ll val = d[num1][1] + 1; lans = min(lans, val); } // 缺少:if (lans == INF) continue; ans += lans % mod * dp[status] % mod; ans %= mod; \end{minted}
\subsection*{错误分析} 当某个自动机状态 $D$ 的 $d_{01}$ 和 $d_{11}$ 均为 $+\infty$ 时,意味着落在该状态的子序列无法完成合法划分,其 $f$ 值为 $0$,不应对答案有任何贡献。
但如果缺少 \texttt{if (lans == INF) continue;},\texttt{lans} 仍为初始值 \texttt{INF}($= 2^{61} - 1$),这个巨大的数值会被乘以 \texttt{dp[status]} 后加入答案,导致结果完全错误。
\subsection*{修复} \begin{minted}{cpp} if (lans == INF) continue; // f=0 的状态不贡献答案 \end{minted}
\subsection*{教训} 使用哨兵值(如 \texttt{INF})初始化 \texttt{min} 变量时,计算结束后必须检查结果是否仍为哨兵值。如果是,说明没有任何有效候选,必须跳过后续计算,否则哨兵值会作为"正常数值"参与运算。
|