1、最长公共子序列问题
https://www.acwing.com/problem/content/899/
写代码时,因为 f ( i-1 , j ) 包含了 f ( i-1 , j-1 ) ,所以一般是不将其写出来的。
初始值的话,根据定义考虑,将 f [ 0 , 0~m ],f [ 0~n , 0 ]初始化为零就好了。
1 #include<iostream> 2 using namespace std; 3 const int N=1010; 4 char a[N],b[N]; 5 int f[N][N]; 6 int main(void){ 7 int n,m; 8 cin>>n>>m; 9 cin>>a+1>>b+1; 10 for(int i=1;i<=n;i++){ 11 for(int j=1;j<=m;j++){ 12 f[i][j]=max(f[i][j-1],f[i-1][j]); 13 if(a[i]==b[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1); 14 } 15 } 16 cout<<f[n][m]<<endl; 17 return 0; 18 }
2、最短编辑距离
https://www.acwing.com/problem/content/904/
1 #include<iostream> 2 using namespace std; 3 const int N=1010; 4 char a[N],b[N]; 5 int f[N][N]; 6 int main(void){ 7 int n,m; 8 cin>>n>>a+1; 9 cin>>m>>b+1; 10 for(int i=1;i<=n;i++) f[i][0]=i; 11 for(int i=1;i<=m;i++) f[0][i]=i;//初始化操作 12 for(int i=1;i<=n;i++){ 13 for(int j=1;j<=m;j++){ 14 f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1); 15 f[i][j]=min(f[i][j],f[i-1][j-1]+(a[i]!=b[j])); 16 } 17 } 18 cout<<f[n][m]; 19 return 0; 20 }
3、编辑距离
最短编辑距离的应用,方法完全相同。
https://www.acwing.com/problem/content/901/
1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 const int N=15,M=1010; 5 int n,m; 6 int f[N][N]; 7 char str[M][N]; 8 int fun(char a[],char b[]){ 9 int la=strlen(a+1); 10 int lb=strlen(b+1); 11 for(int i=0;i<=la;i++) f[i][0]=i; 12 for(int i=0;i<=lb;i++) f[0][i]=i; 13 for(int i=1;i<=la;i++){ 14 for(int j=1;j<=lb;j++){ 15 f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1); 16 f[i][j]=min(f[i][j],f[i-1][j-1]+(a[i]!=b[j])); 17 } 18 } 19 return f[la][lb]; 20 } 21 int main(void){ 22 cin>>n>>m; 23 for(int i=0;i<n;i++){ 24 cin>>str[i]+1; 25 } 26 while(m--){ 27 char s[N]; 28 int limit; 29 cin>>s+1>>limit; 30 int res=0; 31 for(int i=0;i<n;i++){ 32 if(fun(str[i],s)<=limit){ 33 res++; 34 } 35 } 36 cout<<res<<endl; 37 } 38 return 0; 39 }