码迷,mamicode.com
首页 > 其他好文 > 详细

字符串普及题 2

时间:2019-08-13 17:22:43      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:line   题解   strong   期望   字符串   后缀   time   class   kmp   

几天前我还会写普及组题,现在已经不会写了


题意

  给你一个仅由字符 \(\text{H,T}\) 构成的字符串 \(S\)
  有一个初始为空的字符串 \(T\),每次随机在 \(T\) 的末尾添加 \(\text{H}\)\(\text{T}\)
  问当 \(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

标签:line   题解   strong   期望   字符串   后缀   time   class   kmp   

原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/190813c.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!