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