0%

2025-2026 ICPC NERC, Kyrgyzstan Regional Contest 吉尔吉斯斯坦——G. Secret Words(区间 DP 不适合应用于计数问题?或者说你至少要想一下,不同的区间划分会不会造成同样的计数情况)

题目大意

题目描述

给定 nn秘密单词组成的列表,以及一个目标文本 TT
目标文本 TT 由小写英文字母和符号 ? 组成。其中 ? 是通配符,可以匹配秘密单词中的任意一个字母。
你需要求出有多少种方法,可以将整个文本 TT 完全拆分为列表中的单词。
每个单词可以使用任意多次。
输出方案数对 109+710^9 + 7 取模的结果。

输入格式

第一行包含一个整数 nn (1n1001 \le n \le 100)。
接下来 nn 行,每行一个字符串 WiW_i (1Wi101 \le |W_i| \le 10),保证所有单词互不相同。
最后一行包含一个字符串 TT (1T1001 \le |T| \le 100)。

样例 1

1
2
3
4
5
6
7
8
9
7
a
b
c
d
ab
bc
cd
ab?d

输出 1

1
11

样例 1 解释

目标文本为 ab?d? 可以匹配任意字符,即此处的 ? 需要根据选用的单词被“填充”。
可能的拆分方式包括:

  1. [a, b, a, d] (第三个单词为 a,此时 ? 匹配 a

  2. [a, b, b, d]? 匹配 b

  3. [a, b, c, d]? 匹配 c

  4. [a, b, d, d]? 匹配 d

  5. [ab, a, d]

  6. [ab, b, d]

  7. [ab, c, d]

  8. [ab, d, d]

  9. [a, bc, d]

  10. [a, b, cd]

  11. [ab, cd]

样例 2

1
2
3
4
2
a
b
??

输出 2

1
4

样例 2 解释

目标文本为 ??
可能的拆分方式包括:

  1. [a, a]

  2. [a, b]

  3. [b, a]

  4. [b, b]

思路讲解

采用线性 DP 的方式啊,采用线性 DP 的方式。

这题的陷阱就是啊,至少是我踩中的陷阱啊。就是采用了区间 DP 的方式,因为毕竟这个数据范围比较小嘛,很容易想到区间 DP 啊。不过区间 DP 它会,虽然说二叉分裂是不同的,但是划分方式是相同的,是会有这种情况的发生。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
for (int i=0;i<N;++i) {
for (int len=1;len<=10;++len) {
if (i-len+1<0) {
break;
}
// 一个 string view 啊,这个 view 就是从 i 减 len 加一开始,长度为 len 的一个 view。
string_view s_view(s.data()+i-len+1,len);
ll valid_num=0;
// 这个循环就是计算 valid num 的数量。说白了就是长度为 len 的合法单一划分数量。
for (auto &ls:len_words_mtx[len]) {
bool ok=true;
for (int j=0;j<SZ(ls);++j) {
if (ls[j]==s_view[j] || s_view[j]=='?') {

}else {
ok=false;
}
}
if (ok) {
valid_num++;
}
}
// 从 i - len 处转移,一共有 valid num 种转移方法,所以说是乘法原理。
// 注意 i - len 为小于零的时候是空,也是 1 种合法的方案。
dp[i]+=(i-len<0?1:dp[i-len])*valid_num;
dp[i]%=mod;
}
}

AC代码

AC

https://codeforces.com/gym/106169/submission/363004216

心路历程(WA,TLE,MLE……)