Time Limit: 1000 ms   Memory Limit: 256 MB

Description

   给定一个由且仅由字符 'H' , 'T' 构成的字符串$S$.

  给定一个最初为空的字符串$T$ , 每次随机地在$T$的末尾添加 'H' 或者 'T' .

  问当$S$为$T$的后缀时, 在末尾添加字符的期望次数.

Input

  输入只有一行, 一个字符串$S$.

Output

  输出只有一行, 一个数表示答案.

  为了防止运算越界, 你只用将答案对$10^9+7$取模.

Sample Input

Sample Output

HTHT
20

题解

   题目的本质其实就是:从左到右一位一位填字符(0或1,概率都为$0.5$),如果当前字符不满足目标串的相应字符,就要退回到之前的某一位继续匹配,求成功填满整个字符串的期望填充次数。

   其中,“退回”的操作,实际上是为了满足题目所说的“后缀”,这点要清楚,失配后不会从头开始,而是从类似KMP的next位置继续匹配。

 

支持数组:

  那么我们对$S$预处理正常KMP的next数组,和一个数组$g[i][j]$ $(j=0,1)$,表示已正确填好前$i$位字符,第$i+1$位字符填了$j$后,匹配的位置。

  设第$i+1$位正确的字符为$x$,那么有

     $g[i][x]=i+1$

   $g[i][x\text^1]=g[next[i]][x\text^1]$

    如果当前第$i$位我们填入$y$,那么下一步我们就应该从$g[i-1][y]$处开始匹配。

  

期望DP:

  设$f_i$表示当前前$i$位已正确填充好,成功填入下一位$i+1$的期望填充次数,$wrong$为$i+1$位的错误字符。

  转移即为:

  

  $\begin{aligned}
  f_i&=0.5*1+0.5*(1+\sum_{j=g[i][wrong]}^{i}f_j)\\
  f_i&=0.5*1+0.5*(1+f_i+\sum_{j=g[i][wrong]}^{i-1}f_j)\\
  \frac{1}{2}f_i&=0.5*1+0.5*(1+\sum_{j=g[i][wrong]}^{i-1}f_j)\\
  f_i&=2+\sum_{j=g[i][wrong]}^{i-1}f_j
  \end{aligned}$

  第一行什么意思呢?

  我们有$0.5$的概率$1$次填上对的字符;

  也有$0.5$的概率填充$1$次,结果填错了,蹦回$g[i][wrong]$,再一路走到$i+1$。

  

  我们边算期望边处理一个前缀和$sum_i=\sum\limits_{j=0}^{i-1}f_j$,这样公式中求和的部分就变成了:

  $f_i=2+sum_{i}-sum_{g[i][wrong]}$

  答案也就是$sum_{len(S)}$,从$0$一路走到$S$的最后。

  时空复杂度$O(n)$


 #include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=,Mod=1e9+;
char inp[N];
int n,s[N],g[N][],nex[N];
ll sum[N];
ll max(ll x,ll y){return x>y?x:y;}
void kmp(){
nex[]=;
for(int i=,j;i<=n;i++){
j=nex[i-];
while(j&&s[j+]!=s[i]) j=nex[j];
if(s[j+]==s[i]) nex[i]=j+;
else nex[i]=;
}
for(int i=;i<n;i++){
g[i][s[i+]]=i+;
g[i][s[i+]^]=g[nex[i]][s[i+]^];
}
}
int main(){
scanf("%s",inp+);
n=strlen(inp+);
for(int i=;i<=n;i++) s[i]=inp[i]=='T';
kmp();
ll f;
sum[]=;
for(int i=;i<n;i++){
f=(sum[i]+Mod-sum[g[i][s[i+]^]]+)%Mod;
sum[i+]=(sum[i]+f)%Mod;
}
printf("%lld\n",sum[n]);
return ;
}

奇妙代码

string (KMP+期望DP)的更多相关文章

  1. 【XSY2472】string KMP 期望DP

    题目大意 给定一个由且仅由字符'H','T'构成的字符串\(S\). ​ 给定一个最初为空的字符串\(T\) ,每次随机地在\(T\)的末尾添加'H'或者'T'. 问当\(S\)为\(T\)的后缀时, ...

  2. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  3. HDU 4405 期望DP

    期望DP算是第一题吧...虽然巨水但把思路理理清楚总是好的.. 题意:在一个1×n的格子上掷色子,从0点出发,掷了多少前进几步,同时有些格点直接相连,即若a,b相连,当落到a点时直接飞向b点.求走到n ...

  4. POJ 2096 【期望DP】

    题意: 有n种选择,每种选择对应m种状态.每种选择发生的概率相等,每种选择中对应的每种状态发生的概率相等. 求n种选择和m种状态中每种至少发生一次的期望. 期望DP好别扭啊.要用倒推的方法. dp[i ...

  5. ZOJ 3822 Domination 期望dp

    Domination Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem ...

  6. uva11600 状压期望dp

    一般的期望dp是, dp[i] = dp[j] * p[j] + 1; 即走到下一步需要1的时间,然后加上 下一步走到目标的期望*这一步走到下一步的概率 这一题,我们将联通分块缩为一个点,因为联通块都 ...

  7. 期望dp专题

    一直不明白为什么概率是正推,期望是逆推. 现在题目做多了,慢慢好像有点明白了 poj2096 收集bug,  有n个种类的bug,和s个子系统.  每找到一个bug需要一天. 要我我们求找到n个种类的 ...

  8. 【高斯消元】兼 【期望dp】例题

    [总览] 高斯消元基本思想是将方程式的系数和常数化为矩阵,通过将矩阵通过行变换成为阶梯状(三角形),然后从小往上逐一求解. 如:$3X_1 + 2X_2 + 1X_3 = 3$ $           ...

  9. 【期望DP】

    [总览] [期望dp] 求解达到某一目标的期望花费:因为最终的花费无从知晓(不可能从$\infty$推起),所以期望dp需要倒序求解. 设$f[i][j]$表示在$(i, j)$这个状态实现目标的期望 ...

随机推荐

  1. 【Spring实战】--1Spring的核心

    最近面试总会涉及Spring的优点,SpringMVC与Struts2的比较,生活慢慢稳定下来,这些面试还是应了那句话“只顾盲目拉车,不会低头看路”,回过头来还是要好好研究一下Spring,如果仅仅是 ...

  2. Servlet--HttpUtils类

    定义 public class HttpUtils 收集 HTTP Servlet 使用的静态的有效的方法. 方法 1.getRequestURL public static StringBuffer ...

  3. 豹哥嵌入式讲堂:ARM知识概要杂辑(2)- 第一款Cortex-M处理器

    1.天生荣耀:ARM Cortex-M处理器由来 ARM公司自2004年推出ARMv7内核架构时,摒弃了以往"ARM+数字"这种处理器命名方法(ARM11之前的处理器统称经典处理器 ...

  4. 编译原理-NFA构造DFA

    本题摘自北邮的编译原理与技术. 首先,根据此图构造状态转换表 表中第一列第一行表示从第一个符号B通过任意个空转换能到达的节点,Ia表示由此行的状态数组({B,5,1}可以看作0状态)经过一个a可以到达 ...

  5. 获取sap登陆用户名的中文描述

    一.业务场景: 当通过MKPF-USNAM查找ADRP-NAME_LAST时,中间缺少一个表,即USR21.否则,MKPF-USNAM不能和ADRP-PERSNUMBER直接对等. 二.解决方法: D ...

  6. Netty学习笔记(二)

    只是代码,建议配合http://ifeve.com/netty5-user-guide/此网站观看 package com.demo.netty; import org.junit.Before;im ...

  7. Windows下为Lua脚本进行加密处理

    缘由 想对Lua脚本进行安全性处理,可惜一直没有想到很好的解决方案,考虑过用原生Lua将脚本编译成二进制代码,也考虑过用zlib将文件进行加密压缩处理,但是感觉都不是最佳方案,今天忽然想到有个东西叫L ...

  8. 个人微信接入图灵机器人(python版)

    准备工作 itchat,requests 注册图灵账号,创建机器人,获取API-KEY 代码实现 import itchat from itchat.content import * import j ...

  9. Java并发(一)——线程安全的容器(上)

    Java中线程安全的容器主要包括两类: Vector.Hashtable,以及封装器类Collections.synchronizedList和Collections.synchronizedMap: ...

  10. SQL Server 页面查询超时(SOS_SCHEDULER_YIELD等待)

    一.问题概述 问题大概是这样的,有一个功能页面经常查询超时,有时候就算能查询出来也要很长的时间,但是有时又会很快.遇到的这种问题在排除掉网络原因之后基本上可以从查询语句上去找原因. 编译查询SQL语句 ...