DP例题较多,可以根据自己需求食用~

update:下翻有状压DP入门讲解,也只有讲解了(逃~

DP的实质,就是状态的枚举。

一般用DP解决的问题,都是求计数最优问题,所以这类问题,我们也可以用搜索来解决。

但是,之所以出现DP,就是因为在有些情况下,搜索不能以较高的效率求解,题目也不需要记录过程,而DP是直接记录答案,不记录过程,效率较高,所以深受广大OIer的唾弃喜爱。

所以写DP的难点就在如何表示每一个状态并利用它快速推出我们想得到的答案。

让我们通过一些毒瘤经典例题来练习DP吧awa

引入

1.走楼梯

题目传送门

明显这道题就是一个DP,还是很入门那种

但既然是引入,还是有必要讲讲的。

既然这位老哥一次可以跨1或2步,那么每一阶的方案数就是前两阶的方案数之和,即dp[i]=dp[i-1]+dp[i-2]

当然,没有初始值递推是跑不起来的,这道题目的初始值就是dp[0]=1,dp[1]=1站着不动1种,走一步1种。

然后从2~n推一遍,输出dp[n]就可以了。

code

2.数塔问题

题目传送门

作为引入的第二道题目依然水到爆

很明显的,这道题目需要一点贪心的思想,每次选择左上和上方较大的一个,由较大那个数的dp值加上这个点本身输入的那个值,最后遍历最后一行的dp值取max即可。

code

例题

1.传球问题

题目传送门

这道题初一看好像真的想不出该怎么做,但是在同机房大佬的提醒下 应该用DP!

我们用dp[m][n]表示第m次传递后第n个小朋友的传娃娃方法数,很明显,我们需要求的即是dp[m][1]的值。找到边界值:dp[0][1]=1;然后可以发现,一个状态转移方程是无法解决这个比较复杂的dp的,需要添加if语句达到效果。

于是我开始讨论有哪些可能。因为这道题是直接用的dp,并没有构建环,所以这是需要特殊考虑的。然后,我们发现,第i次传递后的点k的方案数,只能由第i-1次传递后的点k的左右两人的方案数之和来得到!

但是如上所述,当这个点是1或n时需要特判,所以情况分为三种:

①这个点是1时:dp[i][j]=dp[i-1][j+1]+dp[i-1][n];

②这个点是n时:dp[i][j]=dp[i-1][j-1]+dp[i-1][1];

③这个点是普通点(非1非n时):dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];

然后双重循环,外层1…->m,内层1…->n,完事输出dp[m][1]即可。

code

2.最小乘车费用

题目传送门

dp题目,本质是完全背包。

完全背包不懂的可以去百度一下

状态转移方程式dp[j]=min(dp[j],dp[j-i]+a[i]);

其实就是一个选不选选多少的问题,只不过循环的顺序需要注意一下。

另外,除了dp[0]以外,其他的dp值都要赋为极大值(没选之前都是无效的所以要极大值)

code

3.最大子段和

题目传送门

这道题目暴力是很容易做出来的...但明显效率太低,重点讲一下从暴力到dp的方法。

1)暴力枚举左右端点,循环求值取max。

这种方法真的暴力。。时间复杂度达到了\(O(n^3)\),在这道题目\(n\leq200000\)的数据范围下会TLE得很惨%%%

2)前缀和枚举优化

比方法1少了循环求值的过程,p[i]表示从1-n的值的和,求区间值直接相减就可以了。

时间复杂度\(O(n^2)\),不出意外的依然会T

3)贪心/DP

这种方法是这道题目的正解,时间复杂度只有\(O(n)\)。

大致思路:设置一个cnt和一个maxx,maxx的初值为第一个输入的数,然后后面每次输入贪心,判断选这个数加入是否要更优,然后缩进左端点,更新cnt,更新ans(取max)

code

4.*最长公共子序列

跟dp没啥关系但是值得了解。

前置知识:求最长上升子序列

p.s. 子序列不是子段,子序列只要求在原串中按顺序出现,不需要连续出现

题目传送门

思路:

知道怎么求最长上升子序列就很简单。因为两个串都是1-n的一个排列,所以元素是相同的。

我们把第一个串的n个数分别对应1-n,让第一个串变成1-n的一个顺序排列(第i个数变成i)

然后按照这个规律,把第2个串也变一下(比如1串中3变成了5,那么2串中的3也要变成5)

然后在2串中找最长上升子序列就可以了,要用二分不然会炸。

原理很好理解,1串经过变化已经变成一个上升串了,又因为两个串中的元素都是相同的,所以找出2串中的最长上升子序列就可以了。

code

5.最大正方形

题目传送门

这道题是在一个01矩阵中找出最大的由1组成的最大的正方形的边长。

输入的原图我们用a数组存起来,当然是二维的。

然后我们用f[i][j]表示以点(i,j)为右下角的正方形的最大边长

拿样例来说,f[2][2]的值就是1,f[3][3]的值就是2(可以画一个22的正方形)

然后每次更新的时候判断,首先这个点的值得是1,因为表示的是右下角,所以就看左上,左和上的f[i][j]值,取min+1作为自己的f值。

为什么要这样做呢?很明显,如果自己的左上,左和上有任意一个是0,那么这个点的f值一定是1(取min+1)而如果它们都是1,那么这个点的f值就是2(能放出边长为2的正方形)

当然,如果这个点的左上,左和上都能作为右下角构建2
2的正方形,那么以这个点为右下角就能构建3*3的正方形(可以画图理解一下)

code

6.最大正方形II

题目传送门

和上一道题目类似,但是拓展时判断的标准从它的值是否是1变成了它是否和左上相同并且和左、上不同(因为要岔开)

代码中要修改的也只有这一处。。

code

*状态压缩DP

动态规划的状态有时候比较恶心,不容易表示出来,需要用一些编码技术,把状态压缩的用简单的方式表示出来。

典型方式:当需要表示一个集合有哪些元素时,往往利用2进制用一个整数表示。比如01背包问题,选表示成1,不选表示成0。

就拿'110101'来说,从低位来看,表示:1选,2不选,3选,4不选,5选,6选。n个物品选取方案的表示信息一定在\([0,2^n-1]\)之间。

动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了。难点在于以下几个方面:状态怎么压缩?压缩后怎么表示?怎么转移?是否具有最优子结构?是否满足后效性?涉及到一些位运算的操作,虽然比较抽象,但本质还是动态规划。

先介绍一下常用的位运算:

  • 按位与:&,把操作的两个数的二进制按位与,两个数的第i位都是1,得到的数的第i位才是1.
  • 按位或:|,把操作的两个数的二进制按位或,任意一个数的第i位是1,得到的数的第i位才是1.
  • 按位异或:^(虽然它平时表示计算符号但是这里它是一个位运算符号):把操作的两个数的二进制按位异或,两个数的第i位不同,得到的数的第i位才是1.
  • 取反:~,只有一个操作数,把这个数的二进制的每一位都取反(0变1,1变0)
  • 左移:<<,把操作数的二进制数左移N位,低位用0补上
  • 右移:>>,把操作数的二进制数右移N位,被移出的舍去

    有什么用呢?

    它快啊!它的计算速度的确比普通的四则运算要快一些,并且也有一些奇怪神奇的作用。

    比如树状数组中会用到的,利用了负数补码的性质,找出x最低位的1的位置,方便树状数组的使用:
int lowbit(int x)
{
return x&(-x);
}

但是需要注意的,位运算的计算优先度较低,请配合括号食用awa

例题后面刷了再更新吧...

【DP入门到入土】的更多相关文章

  1. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  2. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  3. 【dp入门题】【跟着14练dp吧...囧】

    A HDU_2048 数塔 dp入门题——数塔问题:求路径的最大和: 状态方程: dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])+a[i][j];dp[n][j] = ...

  4. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  5. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

  6. hdu3555 Bomb 数位DP入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...

  7. 【专章】dp入门

    动态规划(简称dp),可以说是各种程序设计中遇到的第一个坎吧,这篇博文是我对dp的一点点理解,希望可以帮助更多人dp入门. ***实践是检验真理的唯一标准,看再多文章不如自己动手做几道!!!*** 先 ...

  8. HDU 2084 数塔(简单DP入门)

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  9. 树形dp 入门

    今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...

随机推荐

  1. Json 文件读写以及和IniFile 转换

    JSON 文件是越来越受欢迎了,以前程序配置文件用Ini,Ini 简练,简单.方便,但是也有不少缺点,比如,没有 JSON 直观,无法存储复杂点的数据类型. 于是乎,我封装了一个TJsonFile 的 ...

  2. macbook下使用pycharm2019版本配置远程连接服务器

    pycharm提供了很方便的与服务器同步代码,并执行的插件.我在配置windows版的pycharm时配置成功,在挪用到mac上则遇到了些许问题,终于是解决了,在此记录配置的过程 目的:pycharm ...

  3. vue生成带logo的二维码

    输入命令行下载 npm install vue_qrcodes <template> <div> <qrcode :url="></qrcode&g ...

  4. mysql_新建表:主键、外键等

    序号 命令(中文) 命令(英文呢) 解释 示例 备注 1 主键约束 primary key 不能重复,不能为空 学号 2 外键约束 foreign key 可以重复,依赖主键 学号 3 非空约束 no ...

  5. SQL Server 索引优化 ——索引缺失

    本文我们将重点给出动态视图法发现数据库中缺失的索引.对于索引的调整和新建将不在本文阐述范围,后续将陆续分享相关经验. sys.dm_db_missing_index_details 缺失索引明细,包括 ...

  6. Webform中的前后端分离

    Webform常用的开发方式 (1)运用服务器端控件的aspx页面 (2)一般处理程序+html静态页面+Ajax(所谓的前后端分离) (3)一般处理程序+html模板引擎   这里简单记录html+ ...

  7. IdentityServer4实现OAuth2.0四种模式之客户端模式

    一,准备内容 IdentityServer4 是Asp.net core的一个中间件,用于添加符合OpenId Connect和OAuth2.0规范的终端到Asp.net Core应用.在这里简单介绍 ...

  8. canvas上画出坐标集合,并标记新坐标,背景支持放大缩小拖动功能

    写在前面:项目需求,用户上传一个区位的平面图片,用户可以在图片上添加新的相机位置,并且展示之前已绑定的相机坐标位置,图片支持放大缩小&拖动的功能.新增坐标,页面展示相对canvas定位,保存时 ...

  9. Layui学习笔记(一)—— 关于模块的扩展

    在使用layui的时候,总有官方自带模块不够用想自己扩展的时候,这时候我们就需要扩展模块了. 模块扩展有两种: (一)普通地扩展 layui.define( function (exports) { ...

  10. Web 标准构成

    Web标准不是某一个标准,而是由W3C和其他标准化组织制定的一系列标准的集合.主要包括结构(Structure).表现(Presentation)和行为(Behavior)三个方面. 结构标准:结构用 ...