HDU 2476 String painter

String painter

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6555    Accepted Submission(s): 3168


 

Problem Description
There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can change a segment of characters of a string to any other character you want. That is, after using the painter, the segment is made up of only one kind of character. Now your task is to change A to B using string painter. What’s the minimum number of operations?
 


 

Input
Input contains multiple cases. Each case consists of two lines:
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
 
 


 

Output
A single line contains one integer representing the answer.
 


 

Sample Input
 
zzzzzfzzzzz abcdefedcba abababababab cdcdcdcdcdcd
 
 


 

Sample Output
 
6 7
 
 


 

Source
 


 

Recommend
lcy

 

【题意】

给定两个相同长度的字符串A,B,每次操作可以使一个区间[l,r]变成同一个字符,问最少需要多少次操作时A变成B

 

【分析】

我们先考虑这样一个问题:假如A是空串,A最少需要多少次操作变成B。不难想到区间dp,设dp[i][j]为将A区间[i,j]染成B的最少操作数。

有一个性质:如果两次染色的区间有交, 那么小的区间一定完全包含于大的区间(左右端点也不会重合), 且一定是大区间 在小区间之前染色(否则 小区间完全被覆盖 就没用了)

所以第一次染色 一定是[i, k],   然后B[k + 1, j]可以单独考虑(因为染色不能再和[i, k]有交了)

只要考虑B[i] = B[k]的位置, 如果不是,可以调整染色区域长度 变成右端点的颜色和 B[i]一样。

然后有另外一个性质

如果B[i] = B[j], dp[i][j] = dp[i + 1][j]. 只要第一次染色区域选择[i, j],  就可以和dp[i + 1][j] 对应起来。

所以,dp[i][j]转移分为两部分:

(1)dp[i][j]=min(dp[i][j],dp[i+1][j]+(B[i]==B[i+1]?0:1) )

(2)dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j])  其中k满足B[i]==B[k] i<k<=j

再考虑A串,设f[i]表示A[0]~A[i]==B[0]~B[i]的最小操作数,初始化时假设AB没有一个字符对应相同,即f[i]=dp[0][i] , f[0]特殊处理,f[0]=A[0]==B[0]?0:1; 那么f[i]考虑两部分,

(1)  f[i]=min(f[i-1],f[i]),A[I]==B[i]  

(2)  f[i]=min( f[i] ,f[j] +dp[j+1][i]) 其中0<=j<i ;(可将[j+1,r]视作空串)

 

【代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#define debug(x) cerr<<#x<<" "<<x<<'\n';
using namespace std;
const int N=110;
int n,dp[N][N],f[N];char x[N],y[N];
int main(){
	while(~scanf("%s%s",x+1,y+1)){
		n=strlen(x+1);memset(dp,0,sizeof dp);
		for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) dp[i][j]=j-i+1;
		for(int j=1;j<=n;j++){
			for(int i=j-1;i>=1;i--){
				dp[i][j]=dp[i+1][j]+!(y[i]==y[i+1]);
				for(int k=i+1;k<=j;k++){
					if(y[i]==y[k]){
						dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);
					}
				}
			}
		}
		for(int i=1;i<=n;i++){
			f[i]=dp[1][i];
			if(x[i]==y[i]){
				f[i]=f[i-1];
			}
			else{
				for(int j=1;j<i;j++){
					f[i]=min(f[i],f[j]+dp[j+1][i]);
				}
			}
		}
		printf("%d\n",f[n]);
	}
	return 0;
} 

 

 

posted @ 2019-02-23 16:51  神犇(shenben)  阅读(169)  评论(0编辑  收藏  举报