给定 n 个长度不超过 10 的字符串以及 m 次询问,每次询问给出一个字符串和一个操作次数上限。

对于每次询问,请你求出给定的 n 个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。

每个对字符串进行的单个字符的插入、删除或替换算作一次操作。

输入格式: 第一行包含两个整数 n 和 m。

接下来 n 行,每行包含一个字符串,表示给定的字符串。

再接下来 m 行,每行包含一个字符串和一个整数,表示一次询问。

字符串中只包含小写字母,且长度均不超过 10。

输出格式: 输出共 m 行,每行输出一个整数作为结果,表示一次询问中满足条件的字符串个数。

数据范围: 1≤n,m≤1000

输入样例:

3 2
abc
acd
bcd
ab 1
acbd 2

输出样例:

1
3

代码实现

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010;

int n, m, k, dp[N][N];
char ss[N][N], s[N];
bool check(char* s, char* p) {
    int n = strlen(s + 1), m = strlen(p + 1);
    for(int i = 1; i <= m; ++i) dp[0][i] = i;
    for(int i = 1; i <= n; ++i) dp[i][0] = i;
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1;
            if(s[i] == p[j]) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1]);
            else dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + 1);
        }
    }
    return dp[n][m] <= k;
}
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 0; i < n; ++i) cin >> ss[i] + 1;
    while(m--) {
        int lim, cnt = 0;
        cin >> s + 1 >> k;
        for(int i = 0; i < n; ++i)
            cnt += check(ss[i], s);
        cout << cnt << '\n';
    }
    return 0;
} 
分类: DP

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

友情链接:Ctips' blog, Colza’s blog

站点状态:Status