字符串普及题 2
Posted scx2015noip-as-php
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串普及题 2相关的知识,希望对你有一定的参考价值。
几天前我还会写普及组题,现在已经不会写了
题意
给你一个仅由字符 \(\textH,T\) 构成的字符串 \(S\)。
有一个初始为空的字符串 \(T\),每次随机在 \(T\) 的末尾添加 \(\textH\) 或 \(\textT\)。
问当 \(S\) 为 \(T\) 的后缀时,在末尾添加字符的期望次数(即 \(T\) 的期望长度)。
题解
真的是个普及组题
不考虑构建 \(T\) 串,只考虑构建 \(S\) 串。
那么问题相当于转化为:初始时你在 \(s\) 串的第 \(0\) 位,当你在第 \(i\) 位时,有 \(0.5\) 的概率走到第 \(i+1\) 位,另外 \(0.5\) 的概率走到第 \(fail[i]\) 位。求走到第 \(|S|\) 位的期望步数。
\(fail[i]\) 用 KMP 预处理即可。然后这就是个普及组的期望 \(dp\)……
可以设 \(f[i]\) 表示第一次第 \(i\) 位走到第 \(i+1\) 位的期望步数。
此时转移为 \(f[i] = 0.5\times 1 + 0.5\times (1+f[fail[i]]+f[fail[i]+1]+...+f[i-1]+f[i])\)
后面那一长串的意思就是 到达上一个匹配位置,再逐步走过来。
由于是递推,前缀和优化即可。
也可以设 \(f[i]\) 表示第 \(i\) 位走到第 \(n\) 位的期望步数。
转移为 \(f[i] = 0.5\times f[i+1] + 0.5\times f[fail[i]] + 1\)
移项得 \(f[i+1] = 2\times f[i] - f[fail[i]] + 2\)
不难发现,这种倒推在起点处的性质很好,即 \(f[0] = 0.5\times f[1] + 0.5\times f[0] + 1\),\(f[1]=f[0]+2\)。
我们又知道终点处 \(f[|s|]=0\)。
把每个位置用 \(a\times f[0]+b\) 表示出来即可。反着扫一遍再正着扫一遍 \(S\) 串递推出来所有位置的系数 \(a\) 和 \(b\),得到 \(f[n]\) 的两个系数后就可以求出 \(f[0]\) 了。
以上是关于字符串普及题 2的主要内容,如果未能解决你的问题,请参考以下文章