字符串的扩展距离问题

题目描述:对于长度相同的2个字符串A和B,其距离定义为相应位置字符距离之和。2个非空格字符的距离是它们的ASCII码之差的绝对值;空格与空格的距离为0,空格与其他字符的距离为一个定值k。在一般情况下,字符串A和B的长度不一定相同。字符串A的扩展是在A中插入若干空格字符所产生的字符串。在字符串A和B的所有长度相同的扩展中,有一对距离最短的扩展,该距离称为字符串A和B的扩展距离。对于给定的字符串A和B测试数据:

输入:cmc
snmn
2 (分别表示字符串A、B和定值k)

输出:10,设计一个算法,计算其扩展距离。

算法分析:
这个题我们可以类比于之前的最长公共子序列问题,题目也比较简单,通过动态规划求解,我们定义一个二维数组dp[i][j] 表示第一个字符串已经匹配到第i位,第二个字符串已经匹配到第j位时两者扩展距离的最小值,我们可以看到此时,dp[i][j] 可能由三种情况得到,一种是i和j匹配时扩展距离加上两者的字符的距离dist,另一种是j和(0~i-1)中的某一位匹配,剩下i和空格匹配(或者是i和0~j-1中某一位匹配,j和空格匹配)此时扩展距离只要加上k就可以了
那么我们很容易得到其中的状态转移方程
d p [ i ] [ j ] = m i n ( d p [ i 1 ] [ j 1 ] + d i s t ( i , j ) , m i n ( d p [ i 1 ] [ j ] + t , d p [ i ] [ j 1 ] + t ) )
最后考虑一下边界条件,如果i或者j=0的话, dp[i][0]=i*k , dp[0][j]=j*k;因为都和空格进行了匹配

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=5000;
int dp[maxn][maxn];
string s,k;
int dist(int i,int j)
{
    int p1=s[i-1]-'a';
    int p2=k[j-1]-'a';
    return abs(p1-p2);
}
int main()
{
    memset(dp,0,sizeof(dp));
    cin>>s>>k;
    int t;
    cin>>t;
    int len = max(s.size(),k.size());
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=s.size();i++)
    {
        dp[i][0]=t*i;
    }
    for(int i=1;i<=k.size();i++)
    {
        dp[0][i]=t*i;
    }
    for(int i=1;i<=s.size();i++)
    {
        for(int j=1;j<=k.size();j++)
        {
            dp[i][j]=min(dp[i-1][j-1]+dist(i,j),min(dp[i-1][j]+t,dp[i][j-1]+t));
        }
    }
    int len1=s.size();
    int len2=k.size();
    cout<<dp[len1][len2]<<endl;
    return 0;

}
全部评论

相关推荐

12-01 12:34
已编辑
广东工业大学 Java
如题,fw🐭🐭,加上准备的太晚,大三上已找不到日常实习,导致连锁反应,下学期的暑期实习找不到好的实习,导致秋招找不到中大厂,现在是中小厂Java还有考公的选择,由于有些中小厂工作强度比肩大厂,钱还少,感觉不如考公如果🐮u们是我现在这种情况,会怎么选?
负债的混子:关注你一段时间了,突然发现你头像名字都改了,想必是这段时间压力很大。关于就业还是考公的选择,就像很多牛友说的:不要美化自己没走过的路。你现在想往互联网发展,发现这条路很难走,然后想往考公发展,但是你没走过考公这条路,所以你不知道这条路的压力如何。你今年大三了,还有时间给你做选择,我希望你能够尽快的决定自己的方向,然后一条路走到黑,而不是在这里徘徊,每个人的道路是不一样的,你无法复刻别人的路,你能做的就是尽力的完善自己。 最后,我想说的是,加油,陌生人!
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务