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

与编辑距离思想类似,但是编辑距离每次只能增删改。还涉及到字符串的对齐问题。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 long

string 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;
}


 

 

 

你可能感兴趣的:(HDU 2476 字符串a转化为字符串b需要几次操作 结合编辑距离)