設有字符串X,我們稱在X的頭尾及中間插入任意多個空格後構成的新字符串爲X的擴展串,如字符串X爲“abcbcd”,則字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X的擴展串,這裏“□”代表空格字符。
如果A1是字符串A的擴展串,B1是字符串B的擴展串,A1與B1具有相同的長度,那麼我們定義字符串A1與B1的距離爲相應位置上的字符的距離總和,而兩個非空格字符的距離定義爲它們的ASCII碼的差的絕對值,而空格字符與其它任意字符之間的距離爲已知的定值K,空格字符與空格字符的距離爲O。在字符串A、B的所有擴展串中,必定存在兩個等長的擴展串A1、B1,使得A1與B1之間的距離達到最小,我們將這一距離定義爲字符串A、B的距離。
請你寫一個程序,求出字符串A、B的距離。
輸入文件第一行爲字符串A,第二行爲字符串B,A、B均由小寫字母組成且長度均不超過2000,第三行爲一個整數K,表示空格與其它字符的距離。
輸出文件僅一行包含一個整數,表示要求的字符串A、B的距離。
cmc
snmn
2
10
1≤K≤100
關鍵:
①狀態還是很好設的
②遇到空格這種有點懵,可以分類別,兩個分別是空格和兩個都不是空格,取min即可
③兩個對應的位置都是空格是沒有意義的
④賦初值!
假設全部都是空格 那麼f[i][0]就應該是k*i
一開始把*i給省去了 wa的臉懵
所以dp一定要考慮清楚初值是什麼
非常非常非常重要
#include<bits/stdc++.h>
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
string a,b;
int k;
int f[2001][2001];
int main(){
cin>>a>>b;
read(k);
int len1=a.length(),len2=b.length();
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=len1;++i) f[i][0]=k*i;
for(int i=1;i<=len2;++i) f[0][i]=k*i;
for(int i=1;i<=len1;++i)
for(int j=1;j<=len2;++j){
f[i][j]=min(f[i-1][j]+k,f[i][j-1]+k);//兩個分別爲空格
f[i][j]=min(f[i][j],abs(a[i-1]-b[j-1])+f[i-1][j-1]);//都不爲空格
}
cout<<f[len1][len2]<<endl;
return 0;
}