1052. 设计密码
你现在需要设计一个密码 S,S 需要满足:
S 的长度是 N;
S 只包含小写英文字母;
S 不包含子串 T;
例如:abc 和 abcde 是 abcde 的子串,abd 不是 abcde 的子串。
请问共有多少种不同的密码满足要求?
由于答案会非常大,请输出答案模 109+7 的余数。
输入格式
第一行输入整数N,表示密码的长度。
第二行输入字符串T,T中只包含小写字母。
输出格式
输出一个正整数,表示总方案数模 109+7 后的结果。
数据范围
1≤N≤50,
1≤|T|≤N,|T|是T的长度。
输入样例1:
2
a
输出样例1:
625
输入样例2:
4
cbc
输出样例2:
456924
代码:
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 55, mod = 1e9 + 7;int n, ne[N], f[N][N];
char s[N];/*KMP + 状态机:对于本题来说,要保证设计的密码中不包含子串T,我们可以想到KMP的目的--->快速找到子串出现的起始位置!因此对于本题的第三个要求,不能有子串T,即表示KMP算法中只要j走不到模板串的末尾就一定不包含子串T!1. 这也是一个状态机问题!对于状态机问题,我们首先要确定状态:状态就是:KMP中j来回可以跳到的位置!(即j可以取0 ~ m共m + 1种状态,入口就是0号位置)2. 考虑j可以跳的情况:会发现j可以跳的位置是完全由模式串i的位置决定的,i位置对应的字符可以取(a ~ z),因此对于i的每种选法,j都有一个唯一跳法使得i和j+1位置对应的字符相等!也就是说对于模板串的j对应的m + 1种状态,每种状态都有26种选法(a ~ z),因此:我们就可以建一个具有m + 1个点,每个点都有26条边的图!3. 我们可以从入口0号位置开始跳,跳到的每一个位置都是一个合法的字符串(注意:不能跳到m位置,跳到m位置就表示包含子串T了)4. 也就是说:每一个合法的字符串,都可以一一对应到一种KMP上的状态机的走法。反过来说:每一种合法的KMP走法,都一一对应一个合法的字符串!即:合法字符串的方案数等价于KMP的状态机走法数!我们只要计算统计KMP的j的走法数即可!因此:最终的答案就是从入口开始走,不走到m位置,一共走n步(设计的密码S的长度限制),一共有多少种不同的路线!具体来说:对于模式串i的每一种选法方案,都会对应模板串j的一种走法;j的每一种走法都会对应模式串i的一种选法的合法方案!--------------------------------------- DP分析 ---------------------------------------------------状态表示:f[i][j]表示 “已经” 枚举了第i个字母(或第i步),处于j状态(即KMP中j可以跳到的0 ~ m+1种位置状态)的方案数!状态计算:考虑f[i][j]是有哪个状态(记该状态为A)转移过来的(简而言之:就是当前状态的方案数是由各类A的方案数之和组成)设j状态是由u状态跳过来的,即f[i][j] = f[i - 1][u]解释:当前第i步处于j状态自然是从第i-1步跳过来的,并且是从可以跳到j状态的u状态跳过来的!注意:对于第i步,由于i位置26种选法的不同,j状态是由KMP动态移动求得,可能会出现j状态多次指向同一个位置,所以,准确来说应该是:f[i][j] += f[i - 1][u]由于模式串我们是从0开始的(即枚举的模式串的每一个位置的选法的下标),而对于步数来说是从1开始的:因此,准确来说应该是:f[i + 1][j] += f[i][u]对应到下方代码:u状态是从j状态跳过来的,因此:f[i + 1][u] += f[i][j]分析完毕!(每一个状态都包含了很多种走法)最终答案:f[n][j]的和(j可取0,1,2 ... m-1)*/int main()
{cin >> n >> s + 1;int m = strlen(s + 1);for (int i = 2, j = 0; i <= m; i++){while (j && s[i] != s[j + 1])j = ne[j];if (s[i] == s[j + 1])j++;ne[i] = j;}f[0][0] = 1;for (int i = 0; i < n; i++) // 枚举步数为i + 1(枚举下标为i的字符,i从0开始)for (int j = 0; j < m && j <= i; j++) // 枚举j可以跳到的状态(0 ~ m共m种状态,必然不能跳到m)for (char k = 'a'; k <= 'z'; k++){ // 枚举模式串i可以取的 a-z 26种状态!// 对于模式串i的每种选法,利用KMP找到j可以跳到的位置uint u = j;while (u && k != s[u + 1])u = ne[u];if (k == s[u + 1])u++;// 只要没有跳到m及m之后就是合法方案if (u < m)f[i + 1][u] = (f[i + 1][u] + f[i][j]) % mod;}int res = 0;for (int i = 0; i < m; i++)res = (res + f[n][i]) % mod;cout << res << endl;return 0;
}
1052. 设计密码相关推荐
- 【ACWing】1052. 设计密码
题目地址: https://www.acwing.com/problem/content/1054/ 你现在需要设计一个密码SSS,SSS需要满足:SSS的长度是NNN:SSS只包含小写英文字母:SS ...
- 解锁秋天\秋季借势的海波设计密码!
属于夏季的节气在热潮中离我们远去,一朝秋暮露成霜,荷败千池.白棉万顷.秋菊凌霜.芙蓉独芳.要说一种节气能让大自然都心生敬畏,那便是秋收冬藏的霜降时分.午后阳光不再灼热,于寒冷秋日,更显温暖.品尝一块满 ...
- 免费UI圆角字体素材|字体设计密码:字形设计中“圆角”的应用规范
什么是圆角呢? 是指在字形制作过程为了给字形添加细节而用到的一个方法,在笔画相交或转折处.一般有内.外圆角两种. 外圆角 内圆角 给字形添加圆角虽然可以增加字形的精致感,但也不能随意添加,流于俗套不说 ...
- 【动态规划】状态机模型
整理的算法模板合集: ACM模板 文章目录 A.抛砖引玉 - AcWing 1049. 大盗阿福 B.AcWing 1057. 股票买卖 IV C.AcWing 1058. 股票买卖 V D.AcWi ...
- DP 状态机模型 AcWing算法提高课 详解
状态机模型 AcWing 1049. 大盗阿福 #include <iostream> #include <algorithm> #include <cmath> ...
- acwing提高组 第一章 动态规划
文章目录 数字三角形模型 最长上升子序列模型 背包模型 状态机模型 状态压缩DP 区间DP 树形DP 数位DP 单调队列优化DP 斜率优化DP oj链接 数字三角形模型 AcWing 1015. 摘花 ...
- Acwing算法—动态规划
目录 数字三角形模型 AcWing 898. 数字三角形 AcWing 1015. 摘花生 AcWing 1018. 最低通行费 AcWing 1027. 方格取数 AcWing 275. 传纸条 最 ...
- 算法——AcWing算法提高课中代码和题解
文章目录 第一章 动态规划 (完成情况:64/68) 数字三角形模型 最长上升子序列模型 背包模型 状态机模型 状态压缩DP 区间DP 树形DP 数位DP 单调队列优化DP 斜率优化DP 第二章 搜索 ...
- AcWing-算法提高课【合集】
算法提高 动态规划 数字三角形 1015. 摘花生 1018.最低通行费 1027. 方格取数 最长上升子序列LIS 1017. 怪盗基德的滑翔翼 1014.登山 482.合唱队形 1012. 友好城 ...
最新文章
- jquery笔记___返回值问题
- C++文件读写 打开方式等比较全
- 如何学好计算机专业?
- java 取出集合前两个数据库_【Java】获取两个List中不同的数据(效率非常不错)-Go语言中文社区...
- 设计模式-行为-迭代器
- js只能输入数字[价格等]
- virtualenv杂记
- 【图像处理】——创建一个新的图片
- mysql share mode_mysql锁:mysql lock in share mode 和 select for update
- Java、Javascript、Javaweb三者的区别
- mysql优化表空间_MySQL 优化笔记
- (17/24) webpack实战技巧:生产环境和开发环境并行设置,实现来回切换
- 使用 MySQL C API 访问 MySQL — 示例
- 微型计算机原理与接口周荷琴,微型计算机原理与接口技术周荷琴
- V-Rep机器人仿真软件模型导入部分
- 【3D目标检测】open3D安装与使用
- 《谁动了我的奶酪》读后感 他人感悟
- 窥一斑而知全豹,几分钟带你读懂Java字节码,再也不怕了
- excel函数获取长域名的顶级域名
- 【学习笔记】多线程进阶JUC
热门文章
- 如何获得ditto的数据
- vue css样式 引入背景图写法
- markdown编辑器之editormd使用整合
- FW: 男人必看必看的十部经典电影_拔剑-浆糊的传说_新浪博客
- 《惢客创业日记》2020.06.30(周二)《隐秘的角落》中的原罪
- Duplicate Symbols for Architecture arm64解决办法
- linux permission deny
- 仿百度外卖3_7_1百度地图拖动定位,显示附近地址poi提示搜索
- vscode 添加 includePath
- React事件处理及事件流