#include #include #include #include #include using namespace std; typedef long long ll; typedef ll weight; typedef vector > matrix; static const int inf = INT_MAX / 3; static int dp[32][32]; //http://www.prefield.com/algorithm/math/hungarian.html weight hungarian(const matrix &a) { int n = a.size(), p, q; vector fx(n, inf), fy(n, 0); vector x(n, -1), y(n, -1); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) fx[i] = max(fx[i], a[i][j]); for (int i = 0; i < n; ) { vector t(n, -1), s(n+1, i); for (p = q = 0; p <= q && x[i] < 0; ++p) for (int k = s[p], j = 0; j < n && x[i] < 0; ++j) if (fx[k] + fy[j] == a[k][j] && t[j] < 0) { s[++q] = y[j], t[j] = k; if (s[q] < 0) for (p = j; p >= 0; j = p) y[j] = k = t[j], p = x[k], x[k] = j; } if (x[i] < 0) { weight d = inf; for (int k = 0; k <= q; ++k) for (int j = 0; j < n; ++j) if (t[j] < 0) d = min(d, fx[s[k]] + fy[j] - a[s[k]][j]); for (int j = 0; j < n; ++j) fy[j] += (t[j] < 0 ? 0 : d); for (int k = 0; k <= q; ++k) fx[s[k]] -= d; } else ++i; } weight ret = 0; for (int i = 0; i < n; ++i) ret += a[i][x[i]]; return ret; } int levenshteinDistance(const string& str1, const string& str2) { fill_n((int*)dp, sizeof(dp) / sizeof(dp[0][0]), INT_MAX); for (int i1 = 0; i1 <= str1.size(); ++i1){ dp[i1][0] = i1; } for (int i2 = 0; i2 <= str2.size(); ++i2){ dp[0][i2] = i2; } for (int i1 = 1; i1 <= str1.size(); ++i1){ for (int i2 = 1; i2 <= str2.size(); ++i2){ const int cost = (str1[i1 - 1] == str2[i2 - 1] ? 0 : 1); dp[i1][i2] = min(dp[i1 - 1][i2] + 1, min(dp[i1][i2 - 1] + 1, dp[i1 - 1][i2 - 1] + cost)); } } return dp[str1.size()][str2.size()]; } int main() { for (int N, M; cin >> N >> M;){ map words; cin.ignore(); for (int i = 0; i < N; ++i){ string line; getline(cin, line); istringstream iss(line); string word; while (iss >> word){ ++words[word]; } } vector dictionary; for (int i = 0; i < M; ++i){ string word; cin >> word; dictionary.push_back(word); } matrix m(M, vector(M, -(1LL << 20))); int left = 0; for (map::iterator it = words.begin(); it != words.end(); ++it, ++left){ for (int right = 0; right < M; ++right){ m[left][right] = -levenshteinDistance(it->first, dictionary[right]) * it->second; } } cout << - hungarian(m) - (M - words.size()) * (1LL << 20) << endl; } }