Codeforces 56D Changing a String
http://codeforces.com/contest/56/problem/D
题目大意:
一个字符串变为目标字符串,可以执行插入,置换和删除3种操作,求最少操作数。
思路:dp[i][j]代表当前串前i个变成目标串前j个的最小花费。
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #define ll long long char a[200005],b[200005]; int n,m; ll f[1005][1005]; int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } void dfs(int n,int m){ if (n==0&&m==0){ return; } if (n>=1&&f[n][m]==f[n-1][m]+1){ dfs(n-1,m); printf("DELETE %d\n",m+1); }else if (m>=1&&f[n][m]==f[n][m-1]+1){ dfs(n,m-1); printf("INSERT %d %c\n",m,b[m]); }else{ dfs(n-1,m-1); if (a[n]!=b[m]) printf("REPLACE %d %c\n",m,b[m]); } } int main(){ scanf("%s",a+1);n=strlen(a+1); scanf("%s",b+1);m=strlen(b+1); for (int i=0;i<=n;i++) for (int j=0;j<=m;j++) f[i][j]=0; f[0][0]=0; for (int i=1;i<=n;i++) f[i][0]=i; for (int i=1;i<=m;i++) f[0][i]=i; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) f[i][j]=std::min(std::min(f[i-1][j],f[i][j-1])+1,f[i-1][j-1]+(a[i]!=b[j])); printf("%I64d\n",f[n][m]); dfs(n,m); }