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. java多线程上篇(三) -- 进程通信和线程死锁简单介绍

    进程通信指的是进程间的信息交换 ,IPC(Inter-Process Communication,进程间通信) 进程通信就相当于一种工作方式.沟通形式,进程通信主要指的就是操作系统提供的进程通信工具( ...

  2. LC 3. Longest Substring Without Repeating Characters

    题目描述 Given a string, find the length of the longest substring without repeating characters. Example ...

  3. C语言 - cJSON解析特定格式 含有数组array类型的数据

    在ESP32中使用了cJSON库,发现很好用.最近服务器端的JSON格式越来越多样,还是有些注意点,需要做下笔记记录下来. cJSON *MAC_arry = cJSON_GetObjectItem( ...

  4. 系统集成Facebook授权发布帖子以及获取帖子评论等功能

    公司的业务和海外贸易紧密连接,项目中需要对接Facebook.Google.Twitter相关API,下面详细描述一下我们对接Facebook中遇到的问题 1,注册Facebook账户,Faceboo ...

  5. ubuntu系统里常用的几个命令

    ### ubuntu系统里常用的几个命令 卸载软件: sudo apt-get --purge remove easy-rsa //最后是包名, --purge是可选参数,加上的话移除配置文件 删除文 ...

  6. 无服务架构在IOT的应用场景——使用函数工作流处理DIS数据

    在物联网领域,复杂性往往并非在于传感器,真正的复杂性在于各种传感器产生的大量数据,以及对这些数据的处理,所以开发者不得不花费大量的时间去构建和维护后端服务器来处理这样一个庞大的数据流.而在今天这个敏捷 ...

  7. 基于搜索的贝叶斯网络结构学习算法-K2

    基于搜索的贝叶斯网络结构学习算法-K2 2018-04-05 19:34:18 ItsBlue 阅读数 3172更多 分类专栏: 贝叶斯网络 网络结构学习   版权声明:本文为博主原创文章,遵循CC ...

  8. IdentityServer4密码模式接入现有用户数据表

    具体接入identityserver请看文档,这里只简单列举部分步骤 1.创建一个web项目,引入Identityserver4的nuget包 2.新建一个类,实现IResourceOwnerPass ...

  9. Xamarin开发综述

    https://blog.csdn.net/qq_41647999/article/details/84844357 一. 前言这十来天对Xamarin的学习踩了很多的坑,说来也是一把心酸泪,下面为大 ...

  10. jQuery_jQuery的两把利器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...