2021牛客寒假集训营第一场-A串

链接:https://ac.nowcoder.com/acm/contest/9981/A
来源:牛客网

题目描述

长度不超过nnn,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+7取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,"unoacscc"包含子序列"us",但"scscucu"则不包含子序列"us"

输入描述:

一个正整数n(2≤n≤10^6

输出描述:

一个正整数,为满足条件的字符串数量对10^9+7取模的值

解题思路

看似是用排列组合求方法数的题,但是实际上这道题用dp可以轻松的解决。
定义数组二维数组
f[1000100][3],将长度为i的字符串统计三种类型
① f[i][0] 前i个字符,已含有us字串的数量
② f[i][1] 前i个字符,含有u但不含有s的数量
③ f[i][2] 前i个字符,不含有u的数量

初始状态下
f[1][0] = 0;
f[1][1] = 1;
f[1][2] = 25;

① = ① * 26 + ② ① = ①前i-1个加任意字符 + ②前i-1加字符s
② = ② * 25 + ③ ② = ②前i-1个加除s外的任意字符 + ③前i-1加字符u
③ = ③ * 25     ③ = ③前i-1个加除u外的任意字符

可得到以下状态转移方程
f[i][0] = (f[i - 1][0] * 26 + f[i - 1][1]) % mod;
f[i][1] = (f[i - 1][1] * 25 + f[i - 1][2]) % mod;
f[i][2] = (f[i - 1][2]*25) % mod;
最后输出f[1..n][0]的和模1e9 + 7即为所求答案

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 using ll = long long;
 4 
 5 const int mod = 1e9 + 7;
 6 
 7 ll f[2000000][3];
 8 int main()
 9 {
10     ios::sync_with_stdio(false);
11     cin.tie(0);
12     int n;
13     cin >> n;
14 
15     f[1][0] = 0;
16     f[1][1] = 1;
17     f[1][2] = 25;
18     
19     for (int i = 2; i <= n; i++)
20     {
21         f[i][0] = (f[i - 1][0] * 26 + f[i - 1][1]) % mod;
22         f[i][1] = (f[i - 1][1] * 25 + f[i - 1][2]) % mod;
23         f[i][2] = (f[i - 1][2]*25) % mod;
24     }
25     ll ans=0;
26     for (int i = 0; i <= n; i++)
27         ans = (ans + f[i][0]) % mod;
28     cout << ans;
29     return 0;
30 }

 

posted @ 2021-02-02 23:35  icey_z  阅读(195)  评论(0)    收藏  举报