http://poj.org/problem?id=1159
最少需要补充的字母数=x的长度-x和y的最长公共子序列的长度。
状态的转移方程:
if(i==0||y==0) dp[i][j]=0;
else if(x[i]==y[j]) dp[i][j]=dp[][i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int a[2][5005]; 9 int main() 10 { 11 int n; 12 string s1,s2; 13 while(scanf("%d",&n)!=EOF){ 14 15 cin>>s1; 16 s2=s1; 17 reverse(s1.begin(),s1.end()); 18 memset(a,0,sizeof(a)); 19 for(int i=1;i<=n;i++) 20 { 21 for(int j=1;j<=n;j++) 22 { 23 if(s1[i-1]==s2[j-1]) 24 { 25 a[i%2][j]=a[(i-1)%2][j-1]+1; 26 } 27 else 28 { 29 a[i%2][j]=max(a[(i-1)%2][j],a[i%2][j-1]); 30 } 31 } 32 } 33 printf("%d ",n-a[n%2][n]); 34 } 35 return 0; 36 }
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int a[2][5005]; 9 int main() 10 { 11 int n; 12 string s1,s2; 13 while(scanf("%d",&n)!=EOF){ 14 15 cin>>s1; 16 s2=s1; 17 reverse(s1.begin(),s1.end()); 18 memset(a,0,sizeof(a)); 19 for(int i=1;i<=n;i++) 20 { 21 for(int j=1;j<=n;j++) 22 { 23 a[i%2][j]=max(a[(i-1)%2][j],a[i%2][j-1]); 24 if(s1[i-1]==s2[j-1]) 25 { 26 a[i%2][j]=max(a[i%2][j],(a[(i-1)%2][j-1]+1)); 27 } 28 } 29 } 30 printf("%d ",n-a[n%2][n]); 31 } 32 return 0; 33 }