题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#problem/C
题意:
由字符串 x 通过下列三种操作
1、插入一个字符;
2、删除一个字符;
3、改变一个字符
变换到字符串 y 所需要的最少操作次数
案例:
Input
11 AGTAAGTAGGC
Output
4
思路分析:
状态转移有以下三种情况
1)可以在y[i]后面插入一个数,即d[i-1][j]+1;
2)可以在y[i]后面插入一个数,即d[i][j-1]+1;
3)还有就是看它是否相等,即d[i-1][j-1]+(x[i-1]!=y[j-1]);
所以公式为d[i][j]=min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+(x[i-1]!=y[j-1]))。
处理好边界非常重要,这里需要注意的是对d[0....m][0],d[0][0.....n]的初始化,d[0][j]就是说x[0]是个空串,而y[n]是长度为j的串,让x串变为y串就是删除i个核苷酸。
源代码如下:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #define MAX 1010 6 using namespace std; 7 char x[MAX],y[MAX]; 8 int d[MAX][MAX]; 9 int main() 10 { 11 int m,n,i,j; 12 while(scanf("%d",&m)!=EOF){ 13 scanf("%s",x); 14 scanf("%d %s",&n,y); 15 for(i=0;i<=m;i++) 16 d[i][0]=i; //边界处理 17 for(j=0;j<=n;j++) 18 d[0][j]=j; //边界处理 19 for(i=1;i<=m;i++) //状态转移 20 for(j=1;j<=n;j++) 21 { 22 d[i][j]=min(d[i-1][j]+1,d[i][j-1]+1); 23 d[i][j]=min(d[i][j],d[i-1][j-1]+(x[i-1]!=y[j-1])); 24 } 25 printf("%d ",d[m][n]); 26 } 27 return 0; 28 }