http://acm.hdu.edu.cn/showproblem.php?pid=2476

String painter

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

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

题意:有两个字符串,A串和B串,每次可以对A串一个区间进行涂改,使该区间所有字母变成任意一种字母,求使A串变成B串需要的最少操作次数

题解:首先考虑一个简化的问题,把一个空串涂改成B串需要的操作数,显然可以通过最基本的区间dp进行解决,转移方程为if(B[i]==B[k])dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);else dp[i][j]=min(dp[i][j],min(dp[i][k]+dp[k+1][j],dp[i][k-1]+dp[k][j]));然后考虑A串不是空串,那么如果A[i]==B[i],则有ans[i]=ans[i-1],如果A[i]!=B[i],那么ans[i]=min(ans[j]+dp[j][i])。

普通的循环迭代版本

 #include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<"["<<#x<<"]"<<" is "<<x<<endl;
char ch[],ch2[];
int dp[][],ans[];
const int inf=1e8;
int main(){
while(scanf("%s",ch+)!=EOF){
scanf("%s",ch2+);
int len=strlen(ch+);
for(int i=;i<=len;i++){
for(int j=;j<=len;j++){
if(i>j)dp[i][j]=;
else if(i==j)dp[i][j]=;
else dp[i][j]=inf;
}
}
for(int i=;i<=len;i++){
for(int j=;j+i-<=len;j++){
for(int k=j+;k<=j+i-;k++){
if(ch2[j]==ch2[k])dp[j][j+i-]=min(dp[j][j+i-],dp[j][k-]+dp[k+][j+i-]);
else dp[j][j+i-]=min(dp[j][j+i-],min(dp[j][k]+dp[k+][j+i-],dp[j][k-]+dp[k][j+i-]));
}
}
}
for(int i=;i<=len+;i++){
ans[i]=inf;
}
ans[]=;
for(int i=;i<=len;i++){
if(ch[i]==ch2[i]){
ans[i+]=min(ans[i+],ans[i]);
}
else{
for(int j=;j<=i;j++){
ans[i+]=min(ans[i+],ans[j]+dp[j][i]);
}
}
}
printf("%d\n",ans[len+]);
}
return ;
}

记忆化搜索版本(注意由于sol(1,len)只能保证dp[1][len]被更新,而不能保证所有的dp[i][j]被遍历到,所以需要使用n^2次sol(i,j)保证所有dp[i][j]都被更新了而不再是初始值)

 #include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<"["<<#x<<"]"<<" is "<<x<<endl;
char ch[],ch2[];
int dp[][],ans[];
const int inf=1e8;
int sol(int l,int r){
if(dp[l][r]!=0x3f3f3f3f)return dp[l][r];
if(l>r)return dp[l][r]=;
if(l==r)return dp[l][r]=;
for(int k=l+;k<=r;k++){
if(ch2[k]==ch2[l]){
dp[l][r]=min(dp[l][r],sol(l+,k)+sol(k+,r));
}
else{
dp[l][r]=min(dp[l][r],sol(l+,r)+);
}
}
return dp[l][r];
}
int main(){
while(scanf("%s",ch+)!=EOF){
scanf("%s",ch2+);
int len=strlen(ch+);
memset(dp,0x3f3f3f3f,sizeof(dp));
for(int i=;i<=len;i++){
for(int j=i;j<=len;j++){
sol(i,j);
}
}
// sol(1,len);
for(int i=;i<=len+;i++){
ans[i]=0x3f3f3f3f;
}
ans[]=;
for(int i=;i<=len;i++){
if(ch[i]==ch2[i]){
ans[i+]=min(ans[i+],ans[i]);
}
else{
for(int j=;j<=i;j++){
ans[i+]=min(ans[i+],ans[j]+dp[j][i]);
}
}
}
printf("%d\n",ans[len+]);
}
return ;
}

[一道区间dp][String painter]的更多相关文章

  1. HDU 2476 区间DP String painter

    题解 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm ...

  2. 又一道区间DP的题 -- P3146 [USACO16OPEN]248

    https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...

  3. 再一道区间DP -- P4170 [CQOI2007]涂色

    https://www.luogu.org/problemnew/show/P4170 一道简单的区间DP,注意读入 #include <bits/stdc++.h> #define up ...

  4. 还一道区间DP -- MZOJ 1346: 不老的传说

    http://10.37.2.111/problem.php?id=1346 与上一道染色基本一样,就加了个限制条件(一次最多刷maxd) #include <bits/stdc++.h> ...

  5. 一道区间DP的水题 -- luogu P2858 [USACO06FEB]奶牛零食Treats for the Cows

    https://www.luogu.org/problemnew/show/P2858 方程很好想,关键我多枚举了一次(不过也没多大关系) #include <bits/stdc++.h> ...

  6. 区间dp的典例

    区间dp, 属于dp的一种,顾名思义,便是对区间处理的dp,其中石子归并,括号匹配,整数划分最为典型. (1)石子归并 dp三要素:阶段,状态,决策. 首先我们从第i堆石子到第j堆石子合并所花费的最小 ...

  7. HDU4632:Palindrome subsequence(区间DP)

    Problem Description In mathematics, a subsequence is a sequence that can be derived from another seq ...

  8. POJ2955:Brackets(区间DP)

    Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...

  9. POJ1179Polygon(区间dp)

    啊~~ 被dp摁在地上摩擦的人 今天做了一道区间dp的题(POJ1179Polygon) 题目: Polygon Time Limit: 1000MS   Memory Limit: 10000K T ...

随机推荐

  1. PS错误1

    PS错误1 提示要卸载.不用卸载直接安装即可.还保留了之前的设置. 在安装目录下看看有没有安装PS的exe程序.可能有.

  2. Word 查找替换高级玩法系列之 -- 给数字批量添加空格和下划线

    Word中的查找和替换是一个很强大的功能,很多人都在使用这项功能.查找和替换,顾名思义就是说,查找到符合条件的内容,然后将那些内容替换成我们所需要的内容.下面,我们就通过实例来了解一下查找和替换功能, ...

  3. vmware 安装XP 32位Professional版本

    VMware14 安装XP 专业版,总部报错Dicrectory Boot not found   下载了N多个XP的版本发现,原来是XP版本的问题,现将正确版本写在这里,以备后用 百度网盘共享位置 ...

  4. spring cloud中代理服务器zuul的使用

    spring cloud中代理服务器zuul的使用 主流网关:     zuul     kong 基于nginx的API Gateway     nginx+lua 1.新建项目,选择eureka ...

  5. eclipse New菜单项的显示问题

    设置自己想要的New菜单 链接:http://www.cnblogs.com/shindo/p/7089141.html

  6. 通过getAdaptiveExtension生成的动态类

    通过getAdaptiveExtension生成的动态类 方便调式使用 请放在根目录下

  7. [Office 365] Office 365与Visio 2013/2016兼容性测试

                  Visio Professional 2013 (x64) - (Chinese-Simplified) 详细信息 文件名 cn_visio_professional_20 ...

  8. windows下监控进程的脚本

    相信大家都有这样的需求,某程序(进程)在运行的时候可能挂掉,需要去监控该程序,并在它挂掉的时候重启之,确保该程序能一直运行.比如土net就经常挂,需要监控程序去监控.Linux下面似乎有守护进程的概念 ...

  9. Kafka 快速入门

    Kafka Kafka 核心概念 什么是 Kafka Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.该项目的目标是为处理实时数据提供一个统一.高吞吐.低延迟 ...

  10. K2 BPM_【解决方案】从流程梳理到落地,K2为企业打造流程管理闭环_全业务流程管理专家

    很多企业在进行流程管理体系建设的过程中,往往急于求成,还没有理清楚要“做什么”和“怎么做”,就开始大刀阔斧地进行改革优化.管理目标.建设标准的不统一,使得体系建设之间内容重复.要求冲突等现象层出不穷. ...