DP基础

  • 简单dp
  • 背包问题
  • 记忆化搜索

简单dp

数字三角形

给一个数字构成的三角形,求从顶端走到底部的一条路径,使得路径上的和最大(或者最小)。

        1      2   3    6   5   4     Example_1        7      3   8    8   1   0  5   2   6   100000     Example_2

根据Example_2可以知道贪心显然是不正确的。
可以看出,除了两边的点以外,每个点可以上一层的两个位置之一到达当前点。
如果我们知道上一层的从顶端到达两个位置的最大路径值,那么对于当前点来说,必然选择较大的那个位置转移过来,也就得到了顶端到达当前位置的最大值。
以Example_1为例,

    dp[1] = 1;    dp[2] = dp[1] + 2 = 3;    dp[3] = dp[1] + 3 = 4;    dp[6] = dp[2] + 6 = 11;    dp[5] = max(dp[2], dp[3]) + 5 = 9;    dp[4] = dp[3] + 4 = 8;

最长上升子序列

个数,求上升子序列的最长长度。

上升子序列,即找到 ,满足

71 7 3 5 9 4 8

最长上升子序列长度为4,其中一种可行的方案为1,3,5,9。

做法


  1. 表示以第个数结尾的上升子序列的最长长度。
for (int i = 1; i <= n; ++i) {
    f[i] = 1;
    for (int j = 1; j < i; ++j)
        if (a[j] < a[i])
            f[i] = max(f[i], f[j] + 1);
}

  1. 对于当前位置的数 来说,就是要找到比它小的数结尾的上升子序列的最长长度,用 表示以数值 结尾的上子序列的最长长度,结合树状数组或者线段树维护区间 的最大长度值即可。
    比较大(比如)时,需要对数值先进行离散化

离散化,可以简单地理解为将非常大、不连续的值映射成较小的、连续的值,一一对应。

/**
* 离散化
*/
vector<int> V;
for (int i = 1; i <= n; ++i)
    V.push_back(a[i]);
// 排序
sort(V.begin(), V.end());
// 去重
V.erase(unique(V.begin(), V.end()), V.end());
// 二分映射位置(0 ~ n - 1)
for (int i = 1; i <= n; ++i)
    a[i] = lower_bound(V.begin(), V.end(), a[i]) - V.begin();

背包问题

  • 01背包
  • 完全背包
  • 多重背包

01背包

有一个空间为的背包,有件物品可以选择装入背包,每个物品有价值和体积,求在空间允许的情况下装入的物品价值和最大

简要分析:空间固定的情况下,价值肯定越大越好。或者反过来想,在价值固定的情况下,空间越小越好。

// f[i]表示空间为i时的最大价值。
for (int i = 1; i <= n; ++i) // 枚举物品
    for (int j = W; j >= w[i]; --j) // 倒着做,避免同一物品装入多次
        f[j] = max(f[j], f[j - w[i]] + v[i]);

完全背包

背包空间为,有物品,每种物品有价值和体积,每种物品有无数件,求背包能装入的最大价值。

简要分析:与01背包的区别在于,一种物品是只有一件还是无数件,01背包是倒着做来避免同一物品装入多次,那么完全背包反过来就可以了。

// f[i]表示空间为i时的最大价值。
for (int i = 1; i <= n; ++i) // 枚举物品
    for (int j = w[i]; j <= W; ++j) // 正着做,同一物品可以装入多次
        f[j] = max(f[j], f[j - w[i]] + v[i]);

多重背包

多重背包介于01背包和完全背包之间,每种物品的数量限制为个。

分析:对于每种物品,如果把它视为种物品,每种物品只能取一件,就转化成了01背包问题。但是可能非常大,导致复杂度()过高。这时候需要做一些优化工作。已知用1、2、4、8可以组合0~15的任意一个数值。
二进制下,0~15的数值最多有4位,0000~1111。
,所以对于0~15的数值化为二进制后根据相应位是否为1就可以知道由1、2、4、8哪些数构成。例如,
回到背包问题上,我们可以将分成种物品(最多种),每种物品的数量为1,这样理论上可以组合出中的任意数量。时间复杂度降为

记忆化搜索

本质上还是DP,但是状态之间的转移写成了dfs的形式,所以计算过程中可以减少一些不必要的状态,以及方便边界处理。

POJ 1088 滑雪

Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12/ 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25

分析:对当前位置(x, y)来说,当满足高度大小关系的时候,可以连接到(x - 1, y)、(x, y + 1)、(x + 1, y)和(x, y - 1)。
当然可以将所有位置按高度排序,然后按顺序去DP,时间复杂度为
用记忆化搜索的方法做的话,dfs(x, y)表示从(x, y)出发的最长长度,, 当
因为从(x, y)出发的最长长度是固定的,不存在什么限制条件,所以可以用表示dfs(x, y),令初值为-1,当访问dfs(x, y)时若不为-1,说明计算过了,直接返回即可,这样就避免了重复计算。
当(x, y)超出边界时,直接返回0即可。

 

动态规划(DP)基础的更多相关文章

  1. 【专章】dp基础

    知识储备:dp入门. 好了,完成了dp入门,我们可以做一些稍微不是那么裸的题了. ----------------------------------------------------------- ...

  2. 动态规划dp

    一.概念:动态规划dp:是一种分阶段求解决策问题的数学思想. 总结起来就一句话:大事化小,小事化了 二.例子 1.走台阶问题 F(10):10级台阶的走法数量 所以:F(10)=F(9)+F(8) F ...

  3. 算法-动态规划DP小记

    算法-动态规划DP小记 动态规划算法是一种比较灵活的算法,针对具体的问题要具体分析,其宗旨就是要找出要解决问题的状态,然后逆向转化为求解子问题,最终回到已知的初始态,然后再顺序累计各个子问题的解从而得 ...

  4. 【学习笔记】dp基础

    知识储备:dp入门. 好了,完成了dp入门,我们可以做一些稍微不是那么裸的题了. dp基础,主要是做题,只有练习才能彻底掌握. 洛谷P1417 烹调方案 分析:由于时间的先后会对结果有影响,所以c[i ...

  5. hdu 2089 不要62 (数位dp基础题)

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. poj 2955 Brackets (区间dp基础题)

    We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a ...

  7. DP基础(线性DP)总结

    DP基础(线性DP)总结 前言:虽然确实有点基础......但凡事得脚踏实地地做,基础不牢,地动山摇,,,嗯! LIS(最长上升子序列) dp方程:dp[i]=max{dp[j]+1,a[j]< ...

  8. 树形dp基础

    今天来给大家讲一下数形dp基础 树形dp常与树上问题(lca.直径.重心)结合起来 而这里只讲最最基础的树上dp 1.选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程 ...

  9. 动态规划_基础_最长公共子序列_多种方法_递归/dp

    D: 魔法少女资格面试 题目描述 众所周知,魔法少女是一个低危高薪职业.随着近年来报考魔法少女的孩子们越来越多,魔法少女行业已经出现饱和现象!为了缓和魔法少女界的就业压力,魔法少女考核员丁丁妹决定增加 ...

  10. 动态规划DP的优化

    写一写要讲什么免得忘记了.DP的优化. 大概围绕着"是什么","有什么用","怎么用"三个方面讲. 主要是<算法竞赛入门经典>里 ...

随机推荐

  1. fdisk添加分区引起的Linux Error: 22: Invalid argument

    在Linux服务器(虚拟机)上使用fdisk添加分区.格式化分区后,遇到了Linux Error: 22: Invalid argument错误,操作步骤如下所示 [root@oracle-serve ...

  2. Win7 安装SQL SERVER 2012需要SP1补丁

    在操作系统Win7上安装SQL Server 2012时,报如下错误: 也就是说SQL Server 2012如要要安装在Windows 7 上,则至少需要安装SP1补丁.否则就会弹出上面提示信息.关 ...

  3. Spring IOC/DI和AOP原理

    一 IOC/DI 1. 概念机原理 IOC: Inversion of Control(控制反转)是一种设计思想,就是容器控制应用程序所需要外部资源的创建和管理,然后将其反转给应用程序.对象及其依赖对 ...

  4. python版本升级

    python 2.7.11,下载链接  https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz,如下载速度太慢可在豆瓣pypi搜索下载ht ...

  5. JavaScript数字精度丢失问题总结

    本文分为三个部分 JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 0.1 + 0.2 != ...

  6. 报表开发之批量导入导出excel

    在日常使用报表过程中,会有这样一种情况,你将Excel表分发给各个员工,员工填完后,统一整理成多个Excel,你需要将这些数据,用报表的填报功能,提交录入到数据库中,这样一来可避免到服务器机房录数据的 ...

  7. Manacher's algorithm

    Manacher's algorithm 以\(O(n)\)的线性时间求一个字符串的最大回文子串. 1. 预处理 一个最棘手的问题是需要考虑最长回文子串的长度为奇数和偶数的情况.我们通过在任意两个字符 ...

  8. Excellent Articles

    Lisp The roots of lisp Recursive Functions of Symbolic Expressions and Their Computation by Machine, ...

  9. Linux下快速迁移海量文件的操作记录

    有这么一种迁移海量文件的运维场景:由于现有网站服务器配置不够,需要做网站迁移(就是迁移到另一台高配置服务器上跑着),站点目录下有海量的小文件,大概100G左右,图片文件居多.目测直接拷贝过去的话,要好 ...

  10. MAC下搭建及使用XAMPP的详细教程

    Windows和Linux都可以搭建本地伺服器(LAMP和IIS),Mac當然也可以,下面教你怎麼使用XAMPP在Mac下搭建一個功能齊全的本地伺服器 所需條件 1.Mac系統(廢話) 2.最好有可用 ...