【题目大意】

给出n个字符串,求有多少组字符串之间编辑距离为1~8。

n<=200,∑|S| <= 10^6

【题解】

首先找编辑距离有一个n^2的dp,由于发现只找小于等于8的,所以搜旁边16个状态即可。

复杂度O(n^2|S| * 16)

# include <vector>
# include <stdio.h>
# include <iostream>
# include <string.h>
# include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const int N = 200 + 10, M = 1e6 + 10, AN = 10;
const int mod = 1e9 + 7;

int n, len[M], ans[AN];
vector<char> a[N];
char str[M];

int u, v;
int dp[2][M];
inline int f(int i, int j) {
    if(i == 0) return j;
    if(j == 0) return i;
    if(j < max(1, i-8) || j > min(len[v], i+8)) return 1e9;
    return dp[i&1][j];
}

inline void fin(int i, int j, int s) {
    dp[i&1][j] = s;
}

inline int gans() {
    for (int i=1; i<=len[v] || i<=len[u]; ++i) fin(0, i, 0), fin(1, i, 0);
    for (int i=1; i<=len[u]; ++i)
        for (int j=max(1, i-8), jto = min(i+8, len[v]); j<=jto; ++j) {
            fin(i, j, min(f(i-1, j), f(i, j-1)) + 1);
            if(a[u][i-1] != a[v][j-1]) fin(i, j, min(f(i, j), f(i-1, j-1) + 1));
            else fin(i, j, min(f(i, j), f(i-1, j-1)));
        }
    return f(len[u], len[v]);
}

int main() {
//    freopen("say.in", "r", stdin);
//    freopen("say.out", "w", stdout);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        scanf("%s", str);
        len[i] = strlen(str);
        for (int j=0; str[j]; ++j) a[i].push_back(str[j]);
    }
    for (int i=1, tem; i<=n; ++i) {
        for (int j=i+1; j<=n; ++j) {
            u = i, v = j;
            tem = gans(); 
            if(tem >= 1 && tem <= 8) ++ ans[tem];
        }
    }
    
    for (int i=1; i<=8; ++i) cout << ans[i] << ' ';
    cout << endl;
    return 0;
}
View Code

相关文章:

  • 2022-01-19
  • 2021-05-29
  • 2021-12-22
  • 2021-06-11
  • 2021-08-11
  • 2022-01-14
  • 2021-08-14
  • 2021-08-16
猜你喜欢
  • 2021-08-27
  • 2022-02-12
  • 2021-11-10
  • 2021-05-24
  • 2021-10-09
  • 2021-08-06
  • 2021-06-10
相关资源
相似解决方案