Description
Example
input
3
4 2
a 01
b 10
0110
4 4
a 01
b 10
c 01
d 0110
0110
4 2
a 1
b 10
0110
output
happymorsecode
puppymousecat 3
nonono
Solution
很明显的
d
p
[
i
]
[
j
]
:
dp[i][j]:
dp[i][j]: 前i位以第j个字母结尾的方案数
这题的答案需要mod128,所以当结果为1时,不一定表示方案唯一。
可以再开一个dp数组,记录某个dp状态是否存在进位,按照dp同样的方式进行转移
若最后答案为1且不存在进位,才代表结果唯一
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const int mod = 128;
const int mod2 = 998244353;
char bk[30][10];
char s[maxn];
int dp[maxn][27];
bool upd[maxn][27];
void init(int n,int m) {
for(int i = 0;i <= n;++i)
for(int j = 1;j <= m;++j)
dp[i][j] = -1, upd[i][j] = false;
}
int main() {
int T;scanf("%d",&T);
while(T--) {
int n,m;scanf("%d %d",&n,&m);
for(int i = 1;i <= m;++i) {
char ch[10];scanf("%s %s",ch,bk[i]);
};
scanf("%s",s+1);
init(n,m);
dp[0][1] = 1;
for(int i = 1;i <= n;++i) {
for(int j = 1;j <= m;++j) {
int d = strlen(bk[j]);
if(i < d) continue;
bool flag = true;
for(int k = 0;k < d;++k) {
if(s[i-k] != bk[j][d-k-1]){
flag = false;
break;
}
}
if(!flag) continue;
dp[i][j] = 1;
int sum = 0;
bool f = false;
for(int k = 1;k <= m;++k) {
int d2 = strlen(bk[k]);
if(dp[i-d][k] == -1) continue;
f = true;
sum += dp[i-d][k];
upd[i][j] |= upd[i-d][k];
if(sum >= 128) upd[i][j] |= (bool)1;
sum %= mod;
}
if(!f) dp[i][j] = -1;
else {
dp[i][j] *= sum, dp[i][j] %= mod;
}
}
}
int res = 0, res2 = 0;
bool flag = false, flag2 = false;
for(int j = 1;j <= m;++j) {
if(dp[n][j] != -1) {
flag = true;
res += dp[n][j];
flag2 |= upd[n][j];
if(res >= 128) flag2 |= (bool)1;
res %= mod;
}
}if(!flag) printf("nonono\n");
else {
if(res == 1) {
if(!flag2)
printf("happymorsecode\n");
else printf("puppymousecat %d\n", res);
} else printf("puppymousecat %d\n", res);
}
}
}