HDOJ 4271 Find Black Hand(最短编辑距离)

来源:互联网 发布:vpn怎么修改域名 编辑:程序博客网 时间:2024/06/07 17:11
/*A一道题,真心觉得不容易,各种情况要考虑。不过是一道经典DP问题首先这道题,是一道最短编辑路径问题,很久以前做过这类问题,一直没做了,所以看到这道题时候根本没有往DP方面想。d[i][j]表示,母串ss[i]得到子串s[j]的最小编辑次数,并且i与前面的操作相连。然后这道题,可以出现环,具体处理将母串复制一遍添加到后面。但是同一个字母不能用多次,所以需要分情况处理。比如母串:abcd,子串:abcda,本来应该输出 abcda 1母串长度为len_ss,子串长度为len_s,如果len_ss > len_s * 2,则上面那种情况一定不会出现,因为出现那种情况编辑距离肯定大于len_s否则的话,另外处理,每次从母串ss[]中截取len_ss长度字符串进行操作。*/#include <cstdio>#include <cstring>const int mMax = 200005;const int nMax = 15;int d[mMax][nMax];char ss[mMax];char s[nMax][nMax];int N;int min(int a, int b, int c){if(a <= b && a <= c) return a;if(b <= a && b <= c) return b;return c;}int main(){while(scanf("%s", ss + 1) != EOF){scanf("%d", &N);int i, j, k, l;for(i = 0; i < N; ++ i) scanf("%s", s[i] + 1);int len_ss = strlen(ss + 1);memcpy(ss + len_ss + 1, ss + 1, len_ss * sizeof(char));int _max = nMax, x = 0;for(i = 0; i < N; ++ i){int len_s = strlen(s[i] + 1);for(j = 0; j <= len_s; ++ j)d[0][j] = j;for(j = 0; j <= len_ss * 2; ++ j)d[j][0] = 0;if(len_ss > 2 * len_s){for(j = 1; j <= 2 * len_ss; ++ j){for(k = 1; k <= len_s; ++ k){if(ss[j] == s[i][k])d[j][k] = min(d[j - 1][k - 1], d[j][k - 1] + 1, d[j - 1][k] + 1);elsed[j][k] = min(d[j - 1][k - 1] + 1, d[j][k - 1] + 1, d[j - 1][k] + 1);}if(d[j][k - 1] < _max){_max = d[j][k - 1];x = i;}else if(d[j][k - 1] == _max && (strcmp(s[i] + 1, s[x] + 1) < 0)){x = i;}}}else{for(l = 1; l <= len_ss; ++ l){for(j = 0; j <= len_s; ++ j)d[l - 1][j] = j;for(j = l; j <= l + len_ss - 1; ++ j)d[j][0] = 0;for(j = l; j <= l + len_ss - 1; ++ j){for(k = 1; k <= len_s; ++ k){if(ss[j] == s[i][k])d[j][k] = min(d[j - 1][k - 1], d[j][k - 1] + 1, d[j - 1][k] + 1);elsed[j][k] = min(d[j - 1][k - 1] + 1, d[j][k - 1] + 1, d[j - 1][k] + 1);}if(d[j][k - 1] < _max){_max = d[j][k - 1];x = i;}else if(d[j][k - 1] == _max && (strcmp(s[i] + 1, s[x] + 1) < 0)){x = i;}}}}}printf("%s %d\n", s[x] + 1, _max);}return 0;}

原创粉丝点击