首页 > 其他分享 >自动机

自动机

时间:2024-07-20 14:53:16浏览次数:7  
标签:状态 int 字符串 序列 自动机 dp

简介

自动机是一种通过状态之间的跳转进行计算的数学模型。

当自动机接受一个输入字符时,它使用状态转移函数,依据当前所处的状态和输入的字符跳转至下一个状态。我们常常使用有向图表示一个有限状态自动机。此时,状态在有向图上以结点形式表示;状态转移函数表示为这张图上的有向边的集合。

比如说判断一个二进制串的奇偶性,我们可以建出以下这个自动机:

image

这个自动机初始状态为 \(q_0\),如果最终状态为 \(q_0\),则该二进制串为偶数,否则为奇数。

子序列自动机

首先考虑怎么判断一个字符串 \(T\) 是否是字符串 \(S\) 的子序列。

可以用类似于贪心的方法:令 \(q_i\) 表示当前字符串匹配到了 \(S\) 的第 \(i\) 个字符。\(q_{0}\) 为初始状态。\(q_{-1}\) 表示当前字符串不是 \(S\) 的子序列。而转移 \(\delta(q_i,c)\) 就为 \(i\) 之后第一次字符 \(c\) 的出现位置。若没有,则为 \(-1\)。

例如 \(S=abaab\) 时自动机如下:

image

这时我们可以发现,所有在这个自动机上以 \(q_0\) 为起点,不以 \(q_{-1}\) 为终点的路径都对应着一个子序列,并且这些子序列都是本质不同的。

什么是本质不同子序列 本质不同子序列是指两个长度不等存在字符不等的子序列。即使这两个子序列在原字符串中的下表不同,只要两个字符串相等,那么它们就是本质相同的。

原因很简单:因为自动机中是取最近的一个字符,所以就不会有重复。

然后在这个自动机上做 \(dp\) 即可求出 \(S\) 的本质不同子序列数量。

代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100005, MOD = int(1e9) + 7;

int t, n, dp[MAXN], ans, r[MAXN][26];
string s;

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> s;
  n = s.size(), s = ' ' + s;
  fill(&r[n + 1][0], &r[n + 1][26], n + 1);
  for(int i = n; i >= 0; --i) {
    dp[i] = 0;
    for(int j = 0; j < 26; ++j) {
      r[i][j] = r[i + 1][j];
    }
    if(i < n) {
      r[i][s[i + 1] - 'A'] = i + 1;
    }
  }
  dp[0] = 1, ans = 0;
  for(int i = 0; i <= n; ++i) {
    for(int j = 0; j < 26; ++j) {
      dp[r[i][j]] = (dp[r[i][j]] + dp[i]) % MOD;
    }
    ans = (ans + dp[i]) % MOD;
  }
  cout << ans << "\n";
  return 0;
}

标签:状态,int,字符串,序列,自动机,dp
From: https://www.cnblogs.com/yaosicheng124/p/18313098

相关文章

  • 自动机
    自动机,就是对于每一个状态和给出的元素,可以唯一确定下一个转移的一个模型比如判断一个二进制数的奇偶性,这是一个很难的问题,用正常思路基本解决不了,只有巨佬才能不要自动机解决,我只有用自动机才能勉强明白定义状态\(p_0\)表示考虑完读入的这一部分末尾0为0个的......
  • 【密码学】从有限状态自动机到密钥流生成器
        本文是对流密码内容的拓展,在流密码中种子密钥通过一个伪随机数生成器产生一个与明文等长的伪随机密钥流。而本文的内容就是在回答这样两个问题:伪随机密钥流是如何生成的?流密码、流密钥生成器和有限状态自动机之间是什么关系?一、什么是有限状态自动机?(1)定义  ......
  • [题解]细胞自动机
    给定一个长度为\(n\)的\(01\)串\(s\),用于表示一个环上的细胞的初始状态,其中第\(1\)个细胞与第\(2\)个、第\(n\)个细胞相邻;第\(n\)个细胞与第\(1\)个和第\(n-1\)个相邻。\(0\)表示细胞死亡,\(1\)表示细胞存活。接下来给定\(t\)轮操作,每一轮操作,根据上一轮细胞的状态更改此轮的状态。......
  • d-finite 与 ODE 自动机
    机械化求解整式递推,又称ODE自动机最后还是要自己写一个(用别人的不放心!你就放心吧,我会写使用说明的(定义对函数\(y(x)\),方程\[\sum_{i=0}^na_i(x)y^{(i)}(x)=C(x)\]为其的一个\(n\)阶线性微分方程。若\(C(x)=0\),则其为一个齐次的线性微分方程,并称满足这一方程......
  • 后缀自动机 SAM
    1概述及定义后缀自动机(SAM)是一个强有力的数据结构,可以解决很多经典字符串问题,例如:线性复杂度进行字符串匹配。线性复杂度求出一个字符串的所有不同子串个数。那么我们定义一个字符串\(S\)的SAM是一个可以接受\(S\)所有后缀的最小DFA(确定性有限状态自动机)。也就是说......
  • 基于Matlab中plot的六方元胞自动机+源代码+文档说明
    文章目录源码下载地址项目介绍项目功能界面预览项目备注源码下载地址源码下载地址点击这里下载代码项目介绍运行MainSixGrid.m文件即可默认随机出生,大小为10x10,演化100步,黑色为死亡,白色为存活,规则为邻居数量大于2且小于3时存活,否则死亡有兴趣的话可以通过更改la......
  • AC自动机
    Trie树Trie树又称字典树、单词查找树,是一种能够高效存储和查找字符串合集的数据结构。可以快速地在集合中查询某个字符串。Trie树的本质就是利用字符串之间的公共前缀,将重复的前缀合并在一起。举个例子,有五个字符串,code,cook,five,file,fat,组织成字典树就是下面这个样子:性质:......
  • 元胞自动机模拟系统(复制器规则探索)
    相关链接Conway'sGameoflife官网Glossaryofbasicterms-LifeWikihttps://conwaylife.com/wiki/Glossary_of_basic_terms网页端模拟:(复制器规则)Conway'sGameofLifeAJavaScriptversionofConway'sGameofLife,basedontheHashlife-algorithm.https://co......
  • Trie字典树和AC自动机 (题目&答案)
    A.三年二班的投票题目描述三年级二班已经完成了竞选班长的投票,已知一共有n张投票,每张投票上写了一位同学的名字。投票统计结束后,张老师随意问一个同学的名字,请编程快速检索出,该同学共有几票。输入第一行读入一个整数n,代表产生了n张投票。(n≤)接下来n行,每行有一......
  • AC自动机(查询)
        上面讲了AC自动机是如何建树和建自动机的,这里要讲的是AC自动机的查询和各个数组的功能和作用。    其实AC自动机的查询和KMP算法是及其相近的,都是一个指针跑主串,另一个指针跑ne串(这里就是回跳边)。    话都说到这了,不妨先来看看ne的真实用处吧。......