看到题解处基本上都写的是 dp[i][j] 表示 A 串的前 i 位转到 B 串的前 j 为所消耗的步数
我写的是 dp[i][j] 表示在短串的第 i 位时,前面已经插入了 j 个字符,也就是这个时候短串的第 i-j 位与长串的第 i 位对应
但是一直最高是 33 分,下载了一个数据后还是没看出问题...... 不知是不是思路不可行,如果确实不可行,请大佬指出问题所在
附:数组是从下标 1 开始存的,s 和 t 才是真正有用的数组
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f
#define NUM 2010
using namespace std;
char s[NUM],t[NUM];
string fs,ft;
long long dp[NUM][NUM];
//dp[i][j]表示长串的第i位时,短串插入了j个字符
//问题就转化为了插入与修改
signed main(){
cin >> fs >> ft;
if( fs.length() > ft.length() )
swap( fs,ft );//保证s长度较短
int ls = fs.length(),lt = ft.length();
int cha = lt-ls;//两个串的长度之差
printf( "长度之差为%d\n",cha );
//将两个字符串都往后移动一位
for( int i = 1;i <= ls;i++ )
s[i] = fs[i-1];
for( int i = 1;i <= lt;i++ ){
t[i] = ft[i-1];
if( s[i] == t[i] ) cout << i << "处一样,为" << s[i] << "\n";
}
for( int i = 0;i <= lt;i++ )
for( int j = 0;j <= cha;j++ )
dp[i][j] = INF;
dp[0][0] = 0;//起点
for( int i = 0;i <= lt-1;i++ ){
for( int j = 0;j <= cha;j++ ){
if( dp[i][j] == INF ) continue;
if( i >= j-1 && s[i-j+1] != t[i+1] ){ //如果两个串这个位置不一样
//直接修改
dp[i+1][j] = min( dp[i+1][j],dp[i][j]+1 );
if( j + 1 <= cha )//插入
dp[i+1][j+1] = min( dp[i+1][j+1],dp[i][j]+1 );
}else{
dp[i+1][j] = dp[i][j];
}
}
}
cout << dp[lt][cha];
return 0;
}
WA了的数据:(这么丑的数据有人看吗)
liulnwtyftqqjfdipasgcenuaopnmzzojuueqtyxcanvahxupygushbgoimyqbzmouxsslcyqhfjqhwt
qsoigvriusgsrjsvsfvyybmxbhlwuzkpfslmzpmbqhigippjiwznxdlrgszbgiezexfdhlkyshakgvfxsxzmjvfqbqvmuckmfyaq