前请提示:https://www.cnblogs.com/caiyishuai/p/9047991.html   配合这篇文章食用风味更佳哦!

首先十分感谢henry_y提供的50道dp练习,链接在这—>https://www.cnblogs.com/henry-1202/p/9211398.html

虽然现在只做了30多道题,剩下的题目还没写,想着以后留着复习来用,但是我对dp的理解比以前高出了不少,现在我来说说对dp的想法吧。

目录

一.动态规划的本质,以及它的核心难点:如何判断这题用dp来解

关于我做到的关于dp以外的技巧

一.动态规划的本质,以及它的核心难点:如何判断这题用dp来解

其实说白了,用到动态规划的题目肯定要满足无后效性,最优子问题这两个关键,但是有些十分有趣的现象,就是如果我们看到一道题,别人没有跟你讲这道题正解是用dp做的,你横看竖看这题也不像dp,那怎么办呢?(这里给出一个实例,有兴趣的可以看一下这题 回文字串 https://www.luogu.org/problem/P1435),那么这些什么无后效性的概念对于我们现在来讲就是废话,因为我们是真的看不出来这题竟然能用dp做,那么现在我给出我自己对这些题目的浅薄理解。

首先,要用dp解题应要立于题目本身,题目要求有求“最大”,“最小”,“最优”等字眼时,应该要想到这题可能要用到dp;

其次,没有头绪时不用慌,观察题目给的样例数据,看看数据都是关于什么,比如背包问题,数据常见的给出有关于价值、容量、重量等等关键元素,这时候就要想一下如果我用dp来写这题,该怎么写。

举个例子,我用dp的思路,常见的就是用F[ i ][ j ]这种二维形式来推出答案,这时候我们应该要想, i 能表示什么,j能表示什么,假设出一种可能后,看看能不能、可不可以写出动态转移方程。

这里我给出一个实例,刚刚那题回文字串,看了题目一脸疑惑,第一反应肯定是暴力,硬搜出答案出来,但是肯定会炸裂,那该怎么办?

我们来看它求什么,“最少插入字符数”,你看!最少这个字眼出现了,直接把解题思路集中在贪心、搜索(这个万不得已的时候才用,因为剪枝技术不行的话,99%超时)、dp等找最优解的算法上(欢迎大家来补充,因为我的知识有限,只了解这些。。。),那么如何来区分是贪心还是dp来解题呢?这里我不再进行解答,开头给出的文章有详细的解析。

我们把目光回到那道题目上面,怎么做?我们可以看到样例有大写字母,小写字母,数字等不同的字符,注意到了吗?不同的字符—>种类(找到第一个元素)每个字符占着不同的位置 —>位置(找到第二个元素) 字串的长度—>长度(找到第三个元素)就这么多吧。

我们再来看看题目的要求,回文字串,题目样例是Ab3bd,如果我们插入它的倒序db3bA,即Ab3bddb3bA,不就是个回文字串吗?而且这么做的话,最后字串个数肯定是偶数,因为倒过来加上去字符个数就是2n,那么我们还可以舍弃最后一个字母来加上去,意思是样例是Ab3bd,回文字串把它变成Ab3bdb3bA,把d给删掉一个,不也是个回文字串吗?那么我们就很容易得出结论  加上去的字符数最多是  原字串长度减去1,(这里先看到下面 1 长度 这个元素)但是有个问题,我原本就有对称趋势的字符,如果这么加,不就浪费了吗?就像样例中的b3b,本已回文,何必再加(看到下面 2 种类 这个元素),那么如何判断这些可以构成回文的部分呢?根据刚刚的思路,倒过来后这些本来已经回文的子串还是回文的,那么不就有点像LCS了吗?我们只需找出那些倒过来还是可以弄成回文的子串(就算是断断续续的也无妨),不就问题迎刃而解?(看到下面 3 位置 这个元素)

现在我们要选一下哪些有用,而且要把它们应用在动态转移方程上面

1 长度 找到了长度这个元素!那怎么可以把它用到方程里面,对于样例而言,长度为5,那么我们只能从5开始,从中间位置开始向两边枚举,但是没有dp的思想在里面啊,否决!

2 种类 回文串的种类个数是串的长度/2(单数串长度还要+1)   我们是否能这么设置?f[ i ][ j ]表示前i 个字符一共有J种种类而需要插入的个数构成的回文串这样子的呢?我们也易看到得出的结果跟我下一个需要判断的阶段好像没啥关系,因为我还是要扫一遍,这不就是搜索了吗?否决!

3 位置 刚刚分析过了,如果我倒过来的串的位置与原串的同一位置的字符一样,那不就看出来这是有对称趋势的字符?配合LCS的思路,最后求出来的就是所以有对称趋势的字符的个数的值,那么我们要求出最少插入的值不就是原串长度-求出的值不就是答案呢吗?为什么呢?把那些没有对称趋势的字符复制在它的“对面”,这个字符就与自己的复制体就对称了,不就从而弄出来答案就是剩下的没有对称趋势的字符的个数吗?而剩下的没有对称趋势的字符不就等于原串长度-求出的值。

以上就是我对其中一题的理解,即是当我没有任何思路时,会去想的方法。 绝不是我事先知道这题是dp才往那方向死命想的

总结一下以上的想法,我就是把题目里面能想到的元素都写出来,再根据题目要求一个个去尝试,因此我在做这些题目时,开了一维的数组,发现好像不行,那就开二维,二维不行就上三维,直到把我能想到的且最终有用的元素都用上。

关于我做到的关于dp以外的技巧

1.尼克的任务(https://www.luogu.org/problemnew/solution/P1280)

这道题可谓是惊天水题,太水了,水的我都溺死了,一开始我一股脑的用常规dp思路,所谓常规就是i=1~n;j=1~n;F[ i , j ]=.......,结果发现连样例都过不了,一看题解,正解要倒序......。这题我怨气这么多一是因为这是50道dp里面的第3道,说是入门级别的难度我实属是不敢相信,二是因为我在找题解,看正解为什么应该要用倒序时,发现了一些dalao,他们写题解都是怎样的呢?“唔~普及组水题”“这题显然是....”等等,我很想说一句,但凡你们认真一点,照顾照顾一下我这些菜鸡,写题解时多一点解释,少一点显然,我也不至于对dp一直有种畏惧的心理。额,这些都是题外话,回到题目,这题可能是我见过的第一道要用倒序dp来做的题目(除去背包问题),算是长见识了。最后说一句,这题一点都不水!

2.LIS的n log n 做法(50道题目里面比较多用到)

这个做法我一开始是一脸懵逼的,最后理解了才发现,其实这种做法不仅仅能适用于这里,这更算是一种思想,一种最优化的思想,我觉得有点难解释,我把这种做法比喻成排队吧,如果有人比现在这个队列里面最高的人还要高,就把他放在最前面,如果不够最高那个人高,就在队列里面找到所有比他高的人里面最矮的那一个,然后把它替换,这样有利于把后面的人给加进来,为什么呢?如果一个人170,他想要加入队伍,现在这个队伍里面最高的人是175,第二高的人是168,这时候我把175的换走,人数不变,此时最高的是170,便于以后想要加进来的171、172、173、174的人排到最前面,队伍人数增多,而不是让他们走人。

3.对dp出来一遍的数组再进行dp一遍(https://www.luogu.org/problem/P1108)

长见识了,我现在都云里雾里的对这题

4.dp与离散化的结合(https://www.luogu.org/problem/UVA10635、https://www.luogu.org/problem/P1439)

这几题以后一定要重新做一遍,对于一些有两个排序标准的题目很有帮助,而且我初步了解到了离散化数据的魅力,其实这个理解起来也不难,就是对于随便一串东西,把它做成一个映射,变成有排列顺序的数字1 2 3 4 等等,做完题输出的时候再反向映射一遍,巧妙吧,我特别想问谁发明的,真的牛啤。

4.Dilworth定理的意思:最少的下降序列个数就等于整个序列最长上升子序列的长度  (有些东西记住就好,不要太在意,要不然头顶会凉)

5.断链成环(https://www.luogu.org/problem/P1063)

这个我要重点提一下,因为我对环的知识还没有很深,所以做题常常碰壁,这题也不例外,那这题怎么说呢?这题让我懂得了一个道理,我设出来的东西可以不用,我可以只是为了我的代码简洁,循环起来不用写那么多限制条件,最后输出的时候输出我要求的东西就行。回归正题吧,环的处理有两种,可以选择(i+1)%n的方式,但也可以将n个元素复制一遍,变成2*n个元素,简化代码,我刚刚说的道理就是从2*n个元素这种方法得出来的。总而言之,我之后要做多一点关于环的题目吧。

6.与二分的结合(https://www.luogu.org/problem/P3957)

虽然核心dp代码里面没有用到二分优化什么的,纯属算是题目要求,但是我想说一句,这是2017普及组的题目???相对而言算难的吧.......

7.单调队列优化(https://www.luogu.org/problem/P3089)

又是长见识的时间,单调队列我就不说了,现在我还只会手写队列,等到会用stl库再来写写这题吧。其实做完这题的时候我思考了这样一个问题,既然我dp都在找以前的最优值,那么什么时候可以用类似的算法,把以前的最优都处理一下,直接省掉一重循环(思考ing......)

8.DAG上的dp(https://www.luogu.org/problem/P2883)

一开始这题我连题目都看不懂的,看了题解还算是懂了那么一点(对于一个高考语文分数107即三年巅峰的人来讲,这种题目描述实属是难顶),其实这题我更想把它叫为递推,因为对于每个点直接加上连接点的值就好了,说是dp也无妨吧。

9.这题就想写一下,也没有什么算法和dp结合(https://www.luogu.org/problem/P1133)

这题给我的启发:当一层有后效性时,那就搞两层;两层不够就三层,三层不够.......

10.挺有意思的一个01背包(https://www.luogu.org/problem/P1417)

强烈建议刷过普通01背包的刷一下这题,长下见识。

我不知道以后我遇到dp题还能不能想的出来怎么写,但是这段刷dp的经历令我难忘。

往下一个专题进发——>线段树

谈谈我近一个半月的dp练习的更多相关文章

  1. MySQL查询近一个月的数据

    MySQL查询近一个月的数据 近一个月统计SQL select user_id, user_name, createtime from t_user where DATE_SUB(CURDATE(), ...

  2. python日志按天分割,保存近一个月日志,日志自动清理

    python日志按天分割,保存近一个月日志 import os import logging import re from logging.handlers import TimedRotatingF ...

  3. 来自多校的一个题——数位DP+卡位

    n<=1e9就要考虑倍增.矩阵乘法这种了 假设L=0 考虑枚举二进制下,所有X与R的LCP长度,前len高位 对于第len+1位,假设R的这一位是1 如果一个x的这一位是0了,那么后面可以随便填 ...

  4. HDU 5945 维护一个单调队列 dp

    Fxx and game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Tot ...

  5. xubuntu14.04截图,彻底到Linux一个半月后记

        前言 自学计算机技术,越到后面,越依赖ubuntu,以致于很多时候都是一开机就打开虚拟机上的ubuntu10.04,Linux已经变得越来越重要了. 2014-04-17,ubuntu14.0 ...

  6. 学了近一个月的java web 感想

    对于每天学习的新知识进行一定的总结,是有必要的. 之前我学的每一门知识,我都没有怎么总结自己的问题,也没有怎么去想想该怎样才能学的更好,把知识掌握的更牢固.从现在开始呢,我会每半个月,或每一个月总结总 ...

  7. #umn 来美国近一个月的简单见闻

    时光如梭,到美国已经快要一个月了,从最初12+4飞行的劳累,到一开始每天吃了上顿没下顿的担心,到后来开始上课的不适,现如今生活已经基本步入了正轨,每天上上课写写作业,去rec center打打球健健身 ...

  8. 肝了一个半月的 Java 项目快速开发脚手架:Chewing

    前言 闲来无事,整一个 Java 项目快速开发脚手架. 正文 一.简介 Chewing 是一个简单的 Java 项目快速开发脚手架.既适合需要开发小型项目的小伙伴使用,也适合刚入门的新手用来学习一些常 ...

  9. D. Mysterious Present (看到的一个神奇的DP,也可以说是dfs)

    D. Mysterious Present time limit per test 2 seconds memory limit per test 64 megabytes input standar ...

随机推荐

  1. SciPy 优化

    章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...

  2. 白手起家Django项目发布上篇_linux centos 环境部署

    在项目发布之前,首先准备好我们编写好的Django项目,这个我们在之后博客有写,大家可以去看, 首先,先开始安装linux服务器,作为Django项目的发布服务器.以Vmware虚拟机为例子,大家也可 ...

  3. sessionManager配置

    在sessionManager配置的时候,有两个属性, 在这个类中,cacheManager是要注入到sessionDao中的,但要求sessionDao实现CacheManagerAware接口 C ...

  4. 【pwnable.tw】 alive_note

    突然发现已经两个月没写过WP了,愧疚- -... 此题也算一道分数很高的题目,主要考察Shellcode的编写. 又是一道题目逻辑很简单的题. 首先提供了三个函数 查看,删除,添加 查看函数: 此函数 ...

  5. 最近学习总结 Nodejs express 获取url参数,post参数的三种方式

    express获取参数有三种方法:官网实例: Checks route params (req.params), ex: /user/:id Checks query string params (r ...

  6. STL——翻转字符串

    #include<bits/stdc++.h> using namespace std; int main() { string a = "abc"; string a ...

  7. UVA - 12166 Equilibrium Mobile (修改天平)(dfs字符串表示的二叉树)

    题意:问使天平平衡需要改动的最少的叶子结点重量的个数. 分析:天平达到平衡总会有个重量,这个重量可以由某个叶子结点的重量和深度直接决定. 如下例子: 假设根结点深度为0,结点6深度为1,若以该结点为基 ...

  8. js实现二叉查找树

    二叉树的特点:   像一颗树一样,从顶端往下延伸,最顶端的为根节点,每个节点下面子节点的数不超过两个,没有任何子节点的节点被称为叶子节点, 除了根节点和叶子节点的被称为中间节点. 二叉查找树: 每个节 ...

  9. ajax异步请求数据

    源码1: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  10. 四十六、SAP的Message中E和W区别

    一.如果写的是E,则报红色的信息,如图 效果如下 二.如果是写的是W,则报黄色的信息 效果如下