zoukankan      html  css  js  c++  java
  • [简单DP] HDOJ 4323 Magic Number

    // 编辑距离的方法可以水过这道题

    编辑距离的计算方法即一个不完全的证明见:http://en.wikipedia.org/wiki/Levenshtein_distance

    具体如下图:

    \qquad\operatorname{lev}_{a,b}(i,j) = \begin{cases}
  0 &, i=j=0 \\
  i &, j = 0 \land i > 0 \\
  j &, i = 0 \land j > 0 \\
  \min \begin{cases}
          \operatorname{lev}_{a,b}(i-1,j) + 1 \\
          \operatorname{lev}_{a,b}(j,i-1) + 1 \\
          \operatorname{lev}_{a,b}(i-1,j-1) + [a_i \neq b_j]
       \end{cases} &, \text{ else}
\end{cases}

    # 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;
    }

    最优性证明可能比较复杂。

  • 相关阅读:
    Kubernetes DNS服务配置案例
    Dockerfile常用指令
    Docker常用命令
    Kubernetes常用命令
    阿里云ECS安装Kubernetes问题收集与解答
    712. Minimum ASCII Delete Sum for Two Strings
    845. Longest Mountain in Array
    815. Bus Routes
    204. Count Primes
    190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2624287.html
Copyright © 2011-2022 走看看