题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2395

题目大意:给定两个长度相等,只有小写字母组成的字符串s和t,每步可以把s的一个连续字串“刷“成同一个字母,问至少需要多少步才能把s变成t。比如:s = bbbbbbb, t = aaabccb,最少需要两步可实现将s变成t:bbbbbbb --> aaabbbb --> aaabccb。(字符串长度不超过100)

题解:由于题目历史较为久远,网上鲜有关于此题的题解。以下内容仅个人YY之作,难登大雅之堂。

初见此题有DP的即视感,由于”刷“这个操作随意性强,没有左右的顺序,因此排除一般的线性DP,考虑区间DP。

我认为DP难度在于选择状态,而状态的选取通常与题目的特殊性质紧密相连。而构造状态的技巧在于,考虑怎样的大状态能由小状态更新过来,更新方法与题目性质挂钩

首先预处理出p[l][r][ch]对于s1(终状态)区间[l,r]上底色为ch的情况下,最少需要几步操作变为s1上的对应状态。

    p[l][r][ch] = p[l + 1][r - 1][ch](s1[l] == ch)

    p[l][r][ch] = min{p[l][k][s1[l]] + p[k + 1][j][ch] + 1} (s1[l] != ch)

f[l][r]表示从l到r这段区间,由s2变为s1需要多少步操作。与题目中”刷”的操作挂钩,考虑从l开始刷k个格子全部变为s1[l],这样[l,k]上已经涂满了底色s1[l],后续操作数由p[l][k][s1[l]]转移。

    f[l][r] = f[l + 1][r](s1[l] == s2[l])

    f[l][r] = min{p[l][r][s1[l]] + f[k + 1][r] + 1} (s1[l] != s2[l])

时间复杂度O(len*len*len*26),以为会T,没想到跑得还挺快的…

 //By Ro_mantic 2015-11-04
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cctype>
#include <climits>
#include <string>
#include <algorithm>
using namespace std; const int MaxN = ;
char s1[MaxN + ], s2[MaxN + ];
int len, len1, len2, Minn, p[MaxN + ][MaxN + ][MaxN],
f[MaxN + ][MaxN + ]; void Prepare()
{
len1 = strlen(s1);
for (int i = ; i <= len1 - ; i++)
for (int j = 'a'; j <= 'z'; j++)
if (s1[i] == j) p[i][i][j] = ;
else p[i][i][j] = ;
for (int len = ; len <= len1; len++)
for (int l = ; l <= len1 - len; l++)
for (int ch = 'a'; ch <= 'z'; ch++)
{
int r = l + len - ;
if (s1[l] == ch) p[l][r][ch] = p[l + ][r][ch];
else
{
Minn = p[l + ][r][ch] + ;
for (int k = l + ; k <= r; k++)
Minn = min(p[l + ][k][s1[l]] + p[k + ][r][ch] + , Minn);
p[l][r][ch] = Minn;
}
}
//printf("%d\n", p[0][8]['a']);
} void Solve()
{
len1 = strlen(s1);
for (int i = ; i <= len1 - ; i++)
if (s1[i] == s2[i]) f[i][i] = ; else f[i][i] = ;
for (int len = ; len <= len1; len++)
for (int l = ; l <= len1 - len; l++)
{
int r = l + len - ;
if (s1[l] == s2[l]) f[l][r] = f[l + ][r];
else
{
Minn = f[l + ][r] + ;
for (int k = l + ; k <= r; k++)
Minn = min(p[l + ][k][s1[l]] + f[k + ][r] + , Minn);
f[l][r] = Minn;
}
}
printf("%d\n", f[][len1 - ]);
} int main()
{
while (~scanf("%s", s2))
{
scanf("%s", s1);
Prepare();
Solve();
}
}

String Painter, Chengdu 2008, LA4394的更多相关文章

  1. HDOJ 题目2474 String painter(区间DP)

    String painter Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. HDU2476 String painter

    题意 String painter Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. HDU2476 String painter —— 区间DP

    题目链接:https://vjudge.net/problem/HDU-2476 String painter Time Limit: 5000/2000 MS (Java/Others)    Me ...

  4. hdu 2476 (string painter) ( 字符串刷子 区间DP)

    String painter Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. hdu2476 String painter(区间dp)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2476 Problem Description There are two strings ...

  6. uva live 4394 String painter 间隔dp

    // uva live 4394 String painter // // 问题是,在培训指导dp运动主题,乍一看,我以为只是一点点复杂 // A A磕磕磕,两个半小时后,.发现超过例子.然而,鉴于他 ...

  7. HDU 2476 String painter(区间DP)

    String painter Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. 刷题总结——String painter(hdu2476)

    题目: Problem Description There are two strings A and B with equal length. Both strings are made up of ...

  9. String painter(区间DP)

    There are two strings A and B with equal length. Both strings are made up of lower case letters. Now ...

随机推荐

  1. HDU6444(子段和、分情况比较)

    要点 不难想到gcd一下然后枚举每个开头走一圈,并记录一下数值. 最终答案是分情况的:1.能走几圈走几圈然后加上最后剩余的最大子段和:2.也可能是最后一圈后面的拖后腿了,所以最后一圈没走完就停,即长度 ...

  2. P5021 赛道修建 (NOIP2018)

    传送门 考场上把暴力都打满了,结果文件输入输出写错了.... 当时时间很充裕,如果认真想想正解是可以想出来的.. 问你 长度最小的赛道长度的最大值 显然二分答案 考虑如何判断是否可行 显然对于一个节点 ...

  3. hdu1028 Ignatius and the Princess III(递归、DP)

    Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  4. redis 集合

    > SADD myset1 a b c (integer) > SADD web maiziedu.com (integer) > SADD web maiziedu.com (in ...

  5. 1.Hibernate框架

    1.分层体系结构与持久化 三层体系结构: 分层体系结构: 指的是将系统的组件分隔到不同的层中,每一层中的组件应保持内聚性,并且应大致在同一抽象级           别: 每一层都应与它下面的各层保持 ...

  6. 技巧:开启ubuntu系统的ssh服务

    执行下述命令,安装 openssh 服务器. $ sudo apt-get install openssh-server 执行下面命令,启动 openssh $ sudo service ssh st ...

  7. HTTP.SYS远程代码执行漏洞测试(ms15-034)

    1.HTTP.SYS远程代码执行漏洞简介 首先漏洞编号:CVE-2015-1635(MS15-034 ) 远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未 ...

  8. java——设计一个支持push,pop,top、在恒定时间内检索最小元素的栈。

    普通方法: 需要另外一个栈 用来存放每一时刻的min值 巧妙版: 只需要一个stack,stack中存的是与min的差值 但由于min是两个整数之间的差值,有可能会出现差值超过整数边界值的情况,因此要 ...

  9. 记录CentOS7.X版本下安装MySQL5.7数据库

    记录CentOS7.X版本下安装MySQL5.7数据库  设置rpm下载目录在/opt目录下新建一个目录存放mysql cd /opt sudo mkdir mysql12  下载MySQL的源 wg ...

  10. C# 利用ADO.NET导出大批量数据

    2015年12月,XX项目中需要做一个数据导出功能,当时所有页面的到处功能均已经实现,但有个页面数据量太大,导出过程中导出页面直接卡死.不得已我准备选用ADO.NET来重新完成这个功能,因为考虑到越偏 ...