TopCoder SRM 617 Div1 Hard FarStrings
問題
長さnの文字列tが与えられる。
長さnの文字列で、tとの編集距離がちょうどiであるような文字列を
1≦i≦nなるiについて出力せよ。
制約条件
n≦25
tおよび出力する文字は英小文字からなる
方針
先頭から一文字ずつ作る。
s = abc****みたいな形になっているとき、tとのマンハッタン距離の上限は、*が何ともマッチしない文字であったとき。
距離の下限は*が何ともマッチする文字であったとき。
一文字ずつ試して、残りの部分を*で埋めたとき距離の下限と上限の間に、
目標の編集距離があればよい。
ソースコード
class FarStrings { public: vector <string> find(string t) { int n = t.size(); vector<string> ans; for(int d = 1; d <= n; d++){ string s(n, '*'); rep(i, n){ rep(j, 26){ s[i] = 'a' + j; pi x = dist(t, s); if(x.second <= d && d <= x.first) break; } } ans.pb(s); } return ans; } int dp[30][30], dp2[30][30]; pi dist(const string &a, const string &b){ rep(i, 30) rep(j, 30) dp[i][j] = dp2[i][j] = inf; rep(i, a.size() + 1) dp[i][0] = dp[0][i] = dp2[0][i] = dp2[i][0] = i; rep(i, a.size()) rep(j, b.size()){ if(a[i] == b[j]){ dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j]); dp2[i + 1][j + 1] = min(dp2[i + 1][j + 1], dp2[i][j]); } if(b[j] == '*') dp2[i + 1][j + 1] = min(dp2[i + 1][j + 1], dp2[i][j]); dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j + 1] + 1); dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i + 1][j] + 1); dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + 1); dp2[i + 1][j + 1] = min(dp2[i + 1][j + 1], dp2[i][j + 1] + 1); dp2[i + 1][j + 1] = min(dp2[i + 1][j + 1], dp2[i + 1][j] + 1); dp2[i + 1][j + 1] = min(dp2[i + 1][j + 1], dp2[i][j] + 1); } return mp(dp[a.size()][b.size()], dp2[a.size()][b.size()]); } };