hdu 2476"String painter"(区间DP)
https://www.cnblogs.com/violet-acmer/p/9852294.html
题意:
给定字符串A,B,每次操作可以将字符串A中区间[ i , j ]的字符变为ch,问最少需要多少次操作可以使 A == B。
题解:
这道题,卡了我好久好久,这期间也尝试用了一些骚操作,然而并没有什么卵用,无奈之举,百度找了巨巨的博客看。
看了三四篇博客,在经过自己的纠结,终于弄懂了。
首先,这道题需要经过两次DP:
① : 第一次是求出将空字符串 S 变为 B 所需的最少操作,定义dp[ i ][ j ] : S[ i,......,j ] == B[ i,......,j ] 所需的最少操作。
② : dp[ ][ ] 求出后,然后根据巨巨的解释就是“A串中的字符与B字符串对应的位置可能存在相同的情况,所以又存在减少次数的可能,这里又会再次用DP计算”
最难理解的便是dp[ ][ ]求解的过程。
状态转移方程如下:
); mem(dp,); ;i <= lenA;++i) dp[i][i]=;//S[i]变为B[i]需要一次操作,不要忘了S[]为空字符串 ;len <= lenA;++len)//区间长度 { ;i+len- <= lenA;++i)//求解dp[i,j] { ; //初始化dp[i][j] //dp[i][j]=( S[i+1,j]变为B[i+1,j]所需的最少操作dp[i+1][j] )+( S[i]变为B[i]需要一次操作 ) dp[i][j]=dp[i+][j]+; ;k <= j;++k) if(B[i] == B[k]) dp[i][j]=min(dp[i][j],dp[i+][k-]+dp[k][j]); } }
我的理解:
①如果B[ i+1,......,j ]中的字符都不等于 B[ i ],那么 dp[ i ][ j ]=dp[ i+1 ][ j ]+1 ; 这也就对应了初始化dp[ i ][ j ]语句,却不会执行for( )循环中的 if 语句。
②如果B[ i+1,......,j ]含有字符等于 B[ i ],如图所示
当 k = k1 时,状态转移方程 dp[ i ][ j ]=min( dp[ i ][ j ] , dp[ i+1 ][ k-1 ]+dp[ k ][ j ] ); 还是比较好理解的,就是在将 S[ k1 ] 变为 B[ i ]的时候一次性也将
S[ ①,......,② ] 变成 B[ i ],因为 B[ k1 ] 是第一个等于 B[ i ] 的,所以 [ ①,......,② ]区间并没有等于 B[ i ] 的字符,那么,将 S[ ①,......,② ] 变为"B[ i ]"或"为空"
对之前所求的 dp[ ①,......,② ] 无影响。
当 k = k2 时,为什么还是用 dp[ i+1 ][ k-1 ] 呢?
思路依旧是 k = k1 时的思路,“在将 S[ k2 ] 变为 B[ i ]的时候一次性也将 S[ ①,......,④ ] 变成 B[ i ]”,那么,该如何求解 dp[ ①,......,④ ]呢?
根据状态转移方程 dp[ i ][ j ] = min( dp[ i ][ j ] , dp[ i ][ k-1]+dp[ k ][ j ] ),所以说 整体的dp ≤ 部分的dp,即dp[ i ][ j ] ≤ dp[ i ][ k-1 ]+dp[ k ][ j ]。
当 k = k3,k4,..... 时同理。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) +; char A[maxn],B[maxn]; int dp[maxn][maxn]; int f[maxn]; int Solve() { ); mem(dp,); ;i <= lenA;++i) dp[i][i]=;//S[i]变为B[i]需要一次操作,不要忘了S[]为空字符串 ;len <= lenA;++len)//区间长度 { ;i+len- <= lenA;++i)//求解dp[i,j] { ; dp[i][j]=dp[i+][j]+; ;k <= j;++k) if(B[i] == B[k]) dp[i][j]=min(dp[i][j],dp[i+][k-]+dp[k][j]); } } ;i <= lenA;++i) { f[i]=dp[][i]; if(A[i] == B[i]) f[i]=f[i-]; else { //如果A[i] != B[i] //那么,从[1,i]之间任意位置断开成[1,k]和[k+1,j],求两部分区间的最小值 ;k <= i;++k) f[i]=min(f[i],f[k]+dp[k+][i]); } } return f[lenA]; } int main() { ,B+)) { printf("%d\n",Solve()); } ; }
其实,感觉对 k > k1 时的理解还是有点牵强,先放放吧,过一段时间在回头理解一下,说不定就顿悟了呢。
还望有理解的巨巨留言相告,定感激不尽
hdu 2476"String painter"(区间DP)的更多相关文章
- HDU 2476 String painter(区间dp)
题意: 给定两个字符串,让求最少的变化次数从第一个串变到第二个串 思路: 区间dp, 直接考虑两个串的话太困难,就只考虑第二个串,求从空白串变到第二个串的最小次数,dp[i][j] 表示i->j ...
- HDU 2476 String painter(区间DP+思维)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意:给你字符串A.B,每次操作可以将一段区间刷成任意字符,问最少需要几次操作可以使得字符串 ...
- HDU 2476 String painter(区间DP)
String painter Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- hdu 2476 (string painter) ( 字符串刷子 区间DP)
String painter Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 2476 String painter (区间DP)
题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b 思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数. 再考虑把a变成 ...
- HDU 2476 String painter(记忆化搜索, DP)
题目大意: 给你两个串,有一个操作! 操作时可以把某个区间(L,R) 之间的所有字符变成同一个字符.现在给你两个串A,B要求最少的步骤把A串变成B串. 题目分析: 区间DP, 假如我们直接想把A变成B ...
- hdu2476 String painter(区间dp)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2476 Problem Description There are two strings ...
- HDU2476 String painter —— 区间DP
题目链接:https://vjudge.net/problem/HDU-2476 String painter Time Limit: 5000/2000 MS (Java/Others) Me ...
- uva live 4394 String painter 区间dp
// uva live 4394 String painter // // 这一题是训练指南上dp专题的习题,初看之下认为仅仅是稍微复杂了一点 // 就敲阿敲阿敲,两个半小时后,发现例子过了.然而自己 ...
随机推荐
- 有时候做JQ动画,鼠标经过,它会不停自己抖动不停,解决方法(此处,是兼容IE ,当鼠标经过,遮罩层从下移到上边的JQ动画效果)
<style> .x_sdbb { margin: 60px 0 40px 0; } .x_title2{ background: url(../images/hdb_img17.png) ...
- idea使用破解版mybatis plugin插件失败,idea打不开的解决方案
记一次错误解决方案 打开 idea.vmoptions (Help -> Edit Custom VM Options...) ,在这里进行了修改 加了破解jar包的路径,但是之前的路径中有中文 ...
- Web API 如何请求基于Basic/Bearer 头的方式 C#
public void SetBasicAuthHeader(WebRequest request, String userName, String userPassword) { string au ...
- springmvc拦截器匹配规则
- Django RBAC用户权限设计方案
RBAC基于用户权限系统设置方案 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干 ...
- Android Studio导入jar包
使用开源框架是,可以直接复制源代码到自己的项目(本人在Android Studio中操作报R程序包不存在),也可以使用jar包,下面记录一下今天使用SmartImageView.jar的过程,不记录S ...
- 【XSY2731】Div 数论 杜教筛 莫比乌斯反演
题目大意 定义复数\(a+bi\)为整数\(k\)的约数,当且仅当\(a\)和\(b\)为整数且存在整数\(c\)和\(d\)满足\((a+bi)(c+di)=k\). 定义复数\(a+bi\)的实部 ...
- django-simple-captcha 组件使用
功能 实现验证码 安装 pip install django-simple-captcha== 使用前准备 首先需要加入到 django 的 app 中 更新下数据库 会添加一张新的表 python ...
- wstngfw 初始化的一些配置
wstngfw 初始化的一些配置 1. 引导界面 2. 命令行菜单界面 3. Assign Interfaces (分配接口) Should VLANs be set up now [y|n]? nW ...
- open-falcon详解
先扔出一张官方的架构图, agent是用于采集机器的监控指标,然后每60秒就会push给transfer,agent与transfer是建立了长连接的,传输速度会比较快: transfer接受到数据后 ...