用代码实现给你一个字符串S,S中只有小写英文字母,你需要计算S中含有多少个"helloworld"子序列,答案可能很大,请输出答案对998244353取模之后的结果 某个序列的子序列是指从最初序列除去部分(可能0个)元素但不破坏余下元素的相对位置而形成的新序列。如"abcde","be","acd"是"abcde"的子序列,但"cbe"不是。 Input 第一行一个正整数T(≤T≤ 3×104),表示有T组输入样例 每组样例在一行内输入一个字符串S(∣S∣≤ 105) 对所有测试数据,保证∑∣S∣≤2.5×106 Output 你需要在一行内输出字符串S有多少个"helloworld"子序列,答案可能很大,请输出答案对998244353取模之后的结果
时间: 2023-03-26 19:02:20 浏览: 139
我可以回答这个问题。以下是代码实现:
#include <iostream>
#include <cstring>
using namespace std;
const int mod = 998244353;
const int maxn = 100005;
const int maxm = 10;
char s[maxn];
int dp[maxn][maxm];
int main() {
int T;
cin >> T;
while (T--) {
cin >> s;
int n = strlen(s);
memset(dp, , sizeof(dp));
for (int i = ; i < n; i++) {
if (s[i] == 'h') dp[i][] = 1;
if (i > ) {
for (int j = ; j < maxm; j++) {
dp[i][j] = dp[i-1][j];
}
}
if (s[i] == 'e' && dp[i-1][] > ) dp[i][1] = (dp[i][1] + dp[i-1][]) % mod;
if (s[i] == 'l' && dp[i-1][1] > ) dp[i][2] = (dp[i][2] + dp[i-1][1]) % mod;
if (s[i] == 'l' && dp[i-1][2] > ) dp[i][3] = (dp[i][3] + dp[i-1][2]) % mod;
if (s[i] == 'o' && dp[i-1][3] > ) dp[i][4] = (dp[i][4] + dp[i-1][3]) % mod;
if (s[i] == 'w' && dp[i-1][4] > ) dp[i][5] = (dp[i][5] + dp[i-1][4]) % mod;
if (s[i] == 'o' && dp[i-1][5] > ) dp[i][6] = (dp[i][6] + dp[i-1][5]) % mod;
if (s[i] == 'r' && dp[i-1][6] > ) dp[i][7] = (dp[i][7] + dp[i-1][6]) % mod;
if (s[i] == 'l' && dp[i-1][7] > ) dp[i][8] = (dp[i][8] + dp[i-1][7]) % mod;
if (s[i] == 'd' && dp[i-1][8] > ) dp[i][9] = (dp[i][9] + dp[i-1][8]) % mod;
}
cout << dp[n-1][9] << endl;
}
return ;
}
解释一下,我们用dp[i][j]表示在字符串s的前i个字符中,helloworld的前j个字符已经匹配成功的子序列个数。那么状态转移方程就是:
dp[i][j] = dp[i-1][j] (s[i] != 'h' || j == )
dp[i][j] = (dp[i][j] + dp[i-1][j-1]) % mod (s[i] == 'h' && j > )
dp[i][j] = (dp[i][j] + dp[i-1][j]) % mod (s[i] != 'h' && j > )
最终答案就是dp[n-1][9],其中n是字符串s的长度。
阅读全文