经典DP总结-----1

---------------------做过的DP题目都做不出来,老废物了------------------
DP学的很乱,对于DP的概念理解应该不会有偏差,并且对于DP的解题步骤也总结了一套方法,但是自己拿到一个DP题目却仍然无法不借助题解把它独立做出来。于是便要镇静的去接受现实:
自己dp依旧很烂,总结几点原因。
1.自己做dp题目时,虽然也思考了很久,但最终还是过多的依靠题解,有利有弊。
好处在于一个题目我知道用什么样的方法去解决会更方便,会有很多想法;
坏处在于做DP题目时没有经历过一个系统的思考独立做出来,缺少完整的解题过程,必然会遗漏一些细节处理。最重要的一点,缺乏底气和信心。而底气和信心源于一道道题目和一次次成功。

2.DP的过程是一个实际上就是状态转移。我每次写出的状态转移方程都是从中间一个状态着手,而对于整个dp过程其实并不熟悉。解决方法也好办---->>>花心思不断的模拟和制图,清楚了解每一个转移过程,画上几十张差不多能找到门道。

总结所有见过的经典DP题目,简单的不嫌麻烦,难的更不要放弃。重新来过,重头新学DP,冲冲冲!!!

A - Jumping Cows
注意点:
1.给出跳高药水的顺序不变,但可以跳过某瓶药水。
2.奇数时间服用药水增加跳高能力,偶数时间减少。
3.牛刚开始的跳高能力为0.
解题:
1.确定dp数组含义---->>>奇数时间,偶数时间,可用dp[0][i]表示偶数时间在第i瓶药时最大跳高能力;dp[1][i]表示偶数时间在第i瓶药时最大跳高能力。
2.找出状态转移方程。
在这里插入图片描述

3.定义初始状态。由注意点可知,牛初始跳高能力为0,定义dp[0][0]为0。

B - 反恐训练营
注意点:
1.为了得到更多分数,要子弹类型和恐怖分子类型一致,不难看出是个公共子序列问题
(如果Z既是X的子序列,又是Y的子序列,则称Z为X和Y的公共子序列:此外子序列不必连续,区别与字段和)。
2.输入那一栏中,第一个数字表示子弹和恐怖分子的类型数,并不表示子弹序列长度和恐怖分子序列长度。
3.若从字符串从0开始存,为了使dp[i-1][j-1]不会小于0,for循环从1开始,反正就注意下标;若觉得难处理,换用字符数组从1开始存,肯定不会出问题。
解题:
1.确定dp数组含义---->>>确定要定义一个二维数组dp[i][j],其中i表示序列X的第i位字母,j表示序列Y的第j位字母,dp[i][j]表示搜索到X第i位,Y第j位时最长公共子序列。
2.找出状态转移方程。
在这里插入图片描述

3.找出初始状态。dp[0][0]定义为0。用string,注意将字符从1开始存。(我倾向从1开始存,但要用c语言中的输入输出,加强学习),否则用字符数组,逻辑清晰一点。

        char s2[2100],s3[2100];
        cin>>s2+1;    //从1开始存
        cin>>s3+1;
        int len2=strlen(s2+1);   //从字符1后开始计算长度
        int len3=strlen(s3+1);   

C - FatMouse’s Speed
注意点:
1.体重严格递增,速度严格递减。也就是对体重排序后对于速度找最长下降子序列。
2.本题难在对于老鼠编号的处理上。采用vector容器好一点,但要区分老鼠的编号并不是子序列的长度。
解题:
1.确定dp数组含义---->>>开始认为要开二维数组,代码写到一半,发现有问题。直接dp[i]表示到第i个老鼠时的子序列长度。
2.找出状态转移方程。
在这里插入图片描述

3.找出初始状态。每只老鼠本身代表的长度即为1,因此dp[i]初始都为1.

D - Tickets (再看发现好简单)
1.确定dp数组含义---->>>第i个人时的最小花费时间。
2.状态转移方程---->>>第i个人时花费的最小时间
在这里插入图片描述

3.初始状态。0个人最小时间自然为0,1个人时时间为当前那人时间。

E - Employment Planning
1.确定dp数组含义---->>>题目中涉及到月份,雇佣人数,最小花费。不难想到为第i个月雇佣j个人所需要的最小花费。
2.找出状态转移方程---->>>每个月雇佣人数最少是a[i],由于hire,salary,hire的费用关系,导致具体雇佣多少人不确定,但上限是月份中雇佣最多人数;要先确定上一个月雇佣人数的最少代价,再讨论当前月份要雇佣多少人的最小代价。(本质就是遍历所有的可能情况取最小)
三层循环:
在这里插入图片描述

3.最小代价,当时设定为无穷大,但要将dp[0][0]确定为0,保证转移方程的正常运行。

F - Largest Submatrix
熟悉的三步骤
1.本题i控制行,j控制列。(ok!)
2.子矩阵要求相同字母最多---->>>转化为子矩阵面积最大---->>>转化为子矩阵的长和宽最大。
(与子矩阵中数的和最大类似,都是采用压缩行,重点对列进行DP的过程)
目标明确:压缩行就是统计这一列连续的和自己相似的字母个数;对列的DP采用两个while循环(选定某个值,不断从左边确定所能到达的界限,然后是右边),理解了好久。
在这里插入图片描述

3.初始化将能变成a(含本身)字母全变成a,不能的清0。对于b,c同理。

G - How many ways (运用递归,递归其实不难,我一直没抽时间去学,所以还是怕)
所以顺手学了吧,漫漫长夜
1.明确这个递归函数满足得功能(自己的目的)
2.确定递归的结束边界,执行到哪一步时退出循环。
3.找出满足的递归方程,由于是对自身的小规模调用,注意参数的变化。
需要满足的条件:
1.有递归公式,分解为一个个和自身类似的小问题;
2.有确定的边界,最后能得到一个确定的值。
(突然发现和区间DP好像好像,连需要满足的条件都很类似。再结合做过的题目,发现好多题目都可用递归解决,所以突然想回过头用递归重新做那些题目)


在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值