[简单DP] HDOJ 4323 Magic Number
// 编辑距离的方法可以水过这道题
编辑距离的计算方法即一个不完全的证明见:http://en.wikipedia.org/wiki/Levenshtein_distance
具体如下图:
# include <cstdio> # include <cstring> # define LEN 10 + 2 # define N 1500 + 5 int n, m; char s[LEN]; int len[N]; char dic[N][LEN]; int Abs(int x) { return x>0 ? x:-x; } int Min(int x, int y, int z) { int t = x<y ? x:y; return t<z ? t:z; } int levenshtein(char* s, char* t, int n, int m) { int i, j, d[LEN][LEN]; for (i = 0; i <= n; ++i) d[i][0] = i; for (i = 0; i <= m; ++i) d[0][i] = i; for (i = 1; i <= n; ++i) for (j = 1; j <= m; ++j) { if (s[i-1]==t[j-1]) d[i][j] = d[i-1][j-1]; else d[i][j] = Min(d[i-1][j], d[i][j-1], d[i-1][j-1])+1; } return d[n][m]; } void solve(void) { int i, j, th, lens, cnt; scanf("%d%d", &n, &m); for (i = 0; i < n; ++i) { scanf("%s", dic[i]); len[i] = strlen(dic[i]); } for (i = 0; i < m; ++i) { cnt = 0; scanf("%s%d", s, &th); lens = strlen(s); for (j = 0; j < n; ++j) { if (Abs(lens-len[j]) > th) continue; if (levenshtein(s, dic[j], lens, len[j]) <= th) ++cnt; } printf("%d\n", cnt); } } int main() { int T; scanf("%d", &T); for (int i = 0; i < T; ++i) { printf("Case #%d:\n", i+1); solve(); } return 0; }
最优性证明可能比较复杂。