隐藏页面特效

HDU 2476 String painter

1|0String 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; }

 

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/10423228.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(180)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
历史上的今天:
2017-02-23 2120: 数颜色
2017-02-23 2821: 作诗(Poetize)
2017-02-23 分块常见例题
2017-02-23 P3373 【模板】线段树 2
点击右上角即可分享
微信分享提示