UVA - 1371 Period (二分+dp)

问题

分析

使用二分法定界,然后使用对于不同的mid使用dp进行编辑距离的计算
还有分段,对于do[i][m]<=mid,就可以进行分段
解析:https://blog.csdn.net/accelerator_/article/details/24940849 这个链接里面使用的是刷表法,dp状态转移的过程更加符合思路

#include<iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int maxn=5000+5,maxm=50+5,INF=0x3f3f3f3f;
int kase,len1,len2,dp[maxn][maxm];
char x[maxn],y[maxm];

bool check(int len){
    for(int i=0;i<=len1;++i) dp[i][0]=i;
    for(int j=0;j<=len2;++j) dp[0][j]=j;
    for(int i=1;i<=len1;++i){
        for(int j=1;j<=len2;++j){
            int &ans=dp[i][j];
            ans=INF;
            if(x[i]==y[j]) ans=min(ans,dp[i-1][j-1]);
            else {
                ans = min(ans, dp[i - 1][j - 1] + 1);
                ans = min(ans, dp[i - 1][j] + 1);
                ans = min(ans, dp[i][j-1] + 1);
            }
        }
        if(dp[i][len2]<=len) dp[i][0]=0;
    }
    return dp[len1][len2]<=len;
}

int main(void){
    scanf("%d",&kase);
    while(kase--){
        scanf("%s%s",y+1,x+1);
        len1=strlen(x+1);
        len2=strlen(y+1);
        int left=0,right=len2,mid=(left+right)/2;
        while(left<right){
            if(check(mid)) right=mid;
            else left=mid+1;
            mid=(left+right)/2;
        }
        printf("%d\n",left);
    }
}
发布了50 篇原创文章 · 获赞 0 · 访问量 691

猜你喜欢

转载自blog.csdn.net/zpf1998/article/details/104160866