HDU 2476 字符串a转化为字符串b需要几次操作 结合编辑距离

来源:互联网 发布:php pre match 编辑:程序博客网 时间:2024/05/10 21:10

与编辑距离思想类似,但是编辑距离每次只能增删改。还涉及到字符串的对齐问题。http://blog.csdn.net/vsooda/article/details/8313172

而本题每次修改就修改一个区间。自然地,使用dp[i][j]表示从i 到 j 所需要的修改次数的上界。

初始化dp[i][j]为dp[i+1][j] + 1

如果s2[i] == s2[k]   dp[i][j] = min(dp[i][j], dp[i+1][k] + dp[k+1][j])  因为i 和 k相同 所以i 和 k可以在一次区间染色操作完成,不再需要对i另外计算。 由于有了区间染色,所以,i 到j被划分成了 i+1 到k  k+1 到j 。而且两个子区间都已经被计算过。

使用ans[i]表示到达 i 的所需要的最小染色次数。使用类似dij的算法。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>using namespace std;#define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define linf 1LL<<60#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long longstring s1,s2;int minn,len;int dp[200][200],ans[200];int main() {while (cin >> s1){cin >> s2;len=s1.size();memset(dp,0,sizeof(dp));for (int i=0; i<len; i++) dp[i][i]=1;for (int j=0; j<len; j++) {for (int i=j-1; i>=0; i--) {dp[i][j]=dp[i+1][j]+1;for (int k=i+1; k<=j; k++) {if (s2[i]==s2[k]) {dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);                            }}}}for (int i=0; i<len; i++) {ans[i]=dp[0][i];if (s1[i]==s2[i]) {if (i==0) ans[i]=0;else ans[i]=ans[i-1];}else {for (int j=0; j<i; j++) ans[i]=min(ans[i],ans[j]+dp[j+1][i]);}}printf("%d\n", ans[len-1]);}return 0;}