动态规划经典例题汇总 (附最全题目链接)
本文总结了《王道机试指南》中动态规划(Dynamic Programming)部分的所有例题以及分析思路、状态转移方程等。有助于完整复习动态规划全部内容。为避免大量代码和题干导致失去主线,本文只写思路,代码可在题目链接内的讨论区找到。
一.基本思想
与分治法类似,其基本思想也是将待求解问题分解成若干子问题,先求解子问题,然后从这些子问题的解中得到原问题的解。
与分治法不同的是,分治法会使得有些子问题被重复计算多次。而动态规划的做法是将已解决子问题的答案保存下来,在需要子问题答案的时候便可直接获得,而不需要重复计算,节约效率。
二.经典题目
1. 递推求解问题
1.1斐波那契数列问题 (n阶楼梯上楼问题)
状态转移方程:dp[n] = dp[n-1] + dp[n-2]
2. 最大连续子序列和
2.1(一维) 最大序列和问题
2.2(二维) 最大子矩阵问题
对于二维情况,假设原二维矩阵的最大子矩阵所在的行为 i 到 j 。
- 当 i = j 时,则最大子矩阵为第 i 行的最大连续子序列和。(转化为一维)
- 当 i != j 时,现在我们已经知道最大子矩阵的行,把从第 i 行到第 j 行的所有元素相加,得到一个只有一行的一维数组,则该一维数组的连续最大和就是最大子矩阵。(同样转化为一维)
3.最长递增子序列
3.1 拦截导弹
3.2 最大上升子序列和问题
3.3 合唱队形
4.最长公共子序列
4.1 Coincidence(找两个字符串的最长公共子串)
S1[i] == S2[j]
,即两个字符相同。此时必定存在一个最长公共子串以这个字符结尾。其他部分等价于S1中前 i - 1 个字符和S2中前 j - 1 个字符的最长公共子串。则这个子串的长度比dp[i-1][j-1]
多1。即dp[i][j] = dp[i-1][j-1] + 1
。S1[i] != S2[j]
,那此时最长公共子串为S1中的前 i - 1 个字符和S2中的前 j - 1 个字符中最长公共子串长度的较大者。即dp[i][j] = max{ dp[i-1][j], dp[i][j-1] }
。
状态转移方程 | 条件 |
---|---|
dp[ i ] [ j ] = dp[ i - 1 ] [ j - 1 ] + 1 | S1[ i ] == S2[ j ] |
dp[ i ] [ j ] = max{ dp[ i - 1 ] [ j ], dp[ i ] [ j - 1 ] } | S1[ i ] != S2[ j ] |
但还要注意一下边界情况,当有一个字符串为空时,公共串长度必为0。即dp[i][0] == dp[0][j] == 0
。
相对于暴力枚举的O(2m+n)复杂度降至了O(mn)。
5.背包问题
5.1 0-1背包 (点菜问题)
- 对于容量为j的背包,如果不放入第 i 件物品,那么这个问题就转化为将前 i - 1 个物品放入容量为j的背包的问题,即
dp[i][j] = dp[i-1][j]
。 - 对于容量为j的背包,如果放入第 i 件物品,那么当前背包的容量就变成了 j - w[i] ,并得到了这个物品的价值 v[i]。那么这个问题就转化成了将当前 i - 1 个物品放入容量为 j - w[i] 的背包的问题,即
dp[i][j] = dp[i-1][ j-w[i] ] + v[i]
。
6.其他问题
6.1 放苹果
链接:https://www.nowcoder.com/questionTerminal/4f0c1e21010e4d849bde5297148e81d9?f=discussion
来源:牛客网
User: 菜鸟葫芦娃
- 设dp(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,
- 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m)
dp(m,n) = dp(m,m)
- 当n <= m:不同的放法可以分成两类:
- 有至少一个盘子空着,即相当于
dp(m,n) = dp(m,n-1)
。 - 所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即
dp(m,n) = dp(m-n,n)
。
而总的放苹果的放法数目等于两者的和,即dp(m,n) = dp(m,n-1) + dp(m-n,n)
。
- 有至少一个盘子空着,即相当于
#include <stdio.h>int dp(int m, int n)
{if(n==1) return 1;else if(m==0) return 1;else if(n>m) return dp(m, m);else return dp(m, n-1)+dp(m-n, n);
}int main()
{int m, n;while(scanf("%d %d", &m, &n)!=EOF){printf("%d\n", dp(m, n));}return 0;
}
动态规划经典例题汇总 (附最全题目链接)相关推荐
- ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向、多类型)
ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向.多类型) 一.前言 ヾ(・ω・`。)我把比较常见的类型的动态规划找了一些经典的例题,适合作为新手的入门例题,用于帮助我们对各种不同的动态规划有所了解,很 ...
- 【计算机网络】第三章数据链路层知识点及经典例题汇总
知识点 1.数据链路层使用的信道主要有以下两种类型: 点对点信道.这种信道使用一对一的点对点通信方式. 广播信道.这种信道使用一对多的广播通信方式,因此过程比较复杂.广播信道上连接的主机很多, ...
- 2022天梯赛正式赛(附天梯赛题目链接)
文章目录 L1-1 今天我要赢 (5 分) L1-2 种钻石 (5 分) L1-3 谁能进图书馆 (10 分) L1-4 拯救外星人 (10 分) L1-5 试试手气 (15 分) L1-6 斯德哥尔 ...
- 运筹说 第69期 | 动态规划经典例题讲解
通过前几期的学习,我们已经学会了动态规划的基本概念和基本原理,并且掌握了动态规划模型的建立和具体的求解方法,本期小编带大家学习动态规划在经济管理中的应用. 除了前面讲到的最优路径.资源分配问题外,动态 ...
- 动态规划经典例题:乘积最大连续子数组
题目: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.例如数组:arr[]={1, 2, 3, -2, 4, -3 ...
- 动态规划经典例题-国王的金矿问题
金矿问题 问题概述: 有一位国王拥有5座金矿,每座金矿的黄金储量不同, 需要参与挖掘的工人人数也不同.例如有的金矿储量是500kg黄金,需 要5个工人来挖掘:有的金矿储量是200kg黄金,需要3个工人 ...
- 动态规划经典例题解析
一.不同路径问题 题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角 ...
- 动态规划经典例题:钢条切割
一.递归算法 如果在第i个地方切割,就把钢条分为两个长度为i,n-i的钢条,问题转化为求这切割两个钢条的最大价值之和 考虑到不切割时的价值 只要比较不切割时的价值和所有切割情况价值和的最大值即可 递归 ...
- 数字三角形(动态规划经典例题)
资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜 ...
- 【动态规划·经典例题】鸡蛋的硬度
鸡蛋的硬度 总时间限制: 1000ms 内存限制: 65536kB 描述 最近XX公司举办了一个奇怪(super strange!)的比赛:鸡蛋硬度之王争霸赛.参赛者是来自世 界各地的母鸡,比赛的内容 ...
最新文章
- java striptrailingzeros_java – 为什么不BigDecimal.stripTrailingZeros()总是删除所有尾随零?...
- 那些年困扰 Linux 的蠕虫、病毒和木马
- iptraf 打不开
- 如何制作流畅有力的游戏动画+Skullgirls案例分析
- ajax清请求过程,JS深入基础之Ajax的请求过程
- [expimp]exp导出笔记
- 我滴个乖乖,一万三千颗卫星那
- 怎么去掉字符串最后一个逗号
- 力学 —— 物体固有属性之惯性张量矩阵
- 教程:使用Java以编程方式将PLT转换为PDF或图像
- 移动WEB开发布局中的-box-sizing:border-box
- 树莓派4B连接PCF8591模块
- (7,4)汉明码编码译码及计算最小码距——基于MATLAB编程
- C# VS2017中Windows窗体更改图标
- 网狐大联盟脚本还原数据库
- threejs辉光通道01(UnrealBloomPass layers)
- 【日本中部电力公司开始着手区块链事业】
- 论文笔记-DeepLung: Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification
- 代数与逻辑:作业一 线性模型
- Python+OpenCV教程5:颜色空间转换 追踪视频中特定颜色的物体 消除票据中的红色印章