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. Is Graph Bipartite?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...

  2. eclipse3.62开发第一个java程序HelloWorld

    [学习笔记] 用eclipse3.62开发第一个java程序: 使用eclipse之前们需要先配置一下jdk.window/preference/java/installed JREs,详细请见视频. ...

  3. python对影评进行评论分析,形成词云图

    1 # -*- coding:utf-8 -*-   2 '''   3 抓取豆瓣电影某部电影的评论  4抓取电影   5 网址链接:https://movie.douban.com/subject/ ...

  4. 个人整理Python代码实例

    1.四位数字字母验证码的生成实例 import random if __name__ =="__main__": #四位数字字母验证码的生成 checkcode="&qu ...

  5. MongoDB用户权限管理配置

    MongoDB系列第一课:MongDB简介 MongoDB系列第二课:MongDB环境搭建 MongoDB系列第三课:MongDB用户管理 MongoDB系列第四课:MongoDB数据库.集合.文档的 ...

  6. Pod——状态和生命周期管理及探针和资源限制

    一.什么是Podkubernetes中的一切都可以理解为是一种资源对象,pod,rc,service,都可以理解是 一种资源对象.pod的组成示意图如下,由一个叫”pause“的根容器,加上一个或多个 ...

  7. Http中的同步请求和异步请求

    最近在上springmvc的JSON数据交换的时候,老师下课提了一个课后问题:什么是异步请求?什么是同步请求?我想大部分同学听到这个问题的时候应该和我一样不知所云.现在,给大家分享一篇关于同步请求和异 ...

  8. BZOJ4199 NOI2015品酒大会(后缀树)

    利用SAM建出后缀树,树上每个节点计算一下|right|.right集合中ai的最大.次大.最小.次小值即可. #include<iostream> #include<cstdio& ...

  9. Java Web 深入分析(9) Session 和 Cookie

    前言: session 和cookie都是为了保持服务器和客户端之间交互状态.如果一天的PV有几亿,而一个cookie占200个字节但是也会占用很多带宽?所以大访问量就引用session,但是几百台服 ...

  10. 12.java中参数传递机制---形参和实参

    1.形参:用来接收调用该方法时传递的参数.只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间.因此仅仅在方法内有效. public void swap(int a, int b) { in ...