其他分享
首页 > 其他分享> > HDU-2476 String painter

HDU-2476 String painter

作者:互联网

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

/*
	HDU-2476
	做法 区间DP
	dp[i][j]表示a中i到j段变成b需要的最少次数
	状态转移方程: dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
	为什么不是 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 需要做一下解释
	因为在b字符串中如果b[i]==b[k],那么把a[i]~a[k]刷成b[i]~b[k]就可以少刷一次
	刷[i,k],[k+1,j]和分别刷[i,i],[i+1,k],[k+1,j]是一样的,可操作数会减少。 
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 1010
#define INF 0x3f3f3f3f
int a[maxn],sum[maxn],dp[maxn][maxn];
int main(){
	string str1,str2;
	while(cin>>str1>>str2){
		int n=str1.length();
		memset(dp,0,sizeof(dp));
		for(int j=0;j<n;j++){
			for(int i=j;i>=0;i--){
				dp[i][j]=dp[i+1][j]+1; //先每个单独刷 
				for(int k=i+1;k<=j;k++){ //处理i到j中间所有的刷法 
					if(str2[i]==str2[k]){ //处理b字符串 
						dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
					}
				}
			}
		}
		for(int i=0;i<n;i++) sum[i]=dp[0][i]; //先初始化 
		for(int i=0;i<n;i++){
			if(str1[i]==str2[i]) sum[i]=sum[i-1];//如果对应位置相等,这个位置可以不刷
			else{
				for(int j=0;j<i;j++){ //寻找j来分割区间得到最优解
					sum[i]=min(sum[i],sum[j]+dp[j+1][i]);
				}
			}
		}
		cout<<sum[n-1]<<endl;
	}
	return 0;
}

标签:2476,HDU,String,int,contains,maxn,dp,painter,string
来源: https://blog.csdn.net/zt2650693774/article/details/95895766