| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> python动态规划入门,从斐波那契数列到01背包 -> 正文阅读 |
|
[数据结构与算法]python动态规划入门,从斐波那契数列到01背包 |
? ? ? ? 在学习动态规划之前,我们先明确一下几点——什么是动态规划?动态规划有什么用?什么情况下使用动态规划? ? ? ? ? 什么是动态规划? ? ? ? ? 动态规划是运筹学的一个分支,是对一类问题的最优解法,在实际问题中表现为以空间换取时间。不同于贪心算法,动态规划的每一个状态绝对是由上一个状态推导而出。 ????????动态规划有什么用? ? ? ? ??动态问题将已解决的子问题保存下来,需要子问题答案时可以直接获得,一些问题不使用动态规划时间复杂度可以达到(2**n)而使用动态规划可以有效降低其时间复杂度。 ????????什么情况下使用动态规划? ? ? ? ? 以下几类问题适合使用动态规划解决:
????????最长上升子序列长度 ????????能不能选出k个数使得和是Sum 反之,若题目要求你把所有情况列举出来,如“无价值属性01背包问题,要求你输出所有重量为w的情况” ? ? ? ? 在正式讲解例题前务必熟记动态规划问题解决思路 ????????动态规划问题的解决思路: 1. ?确定dp数组(dp table)以及下标的含义 有些同学python基础没打好,只知道有python,却不知道如何在python中创建数组,这里提供浅拷贝和深拷贝两种方法,平时使用浅拷贝足以:
1.斐波那契数列 代码如下:
这里我们学习了最简单的状态转移——递推,每次的状态皆有前两次状态得到 2.爬楼梯 给定一个n(1<=n<=5)代表总共有 阶楼梯,一开始在第0阶,每次可以爬1或者2个 台阶,问总共有多少种不同的方法可以爬到楼顶。 代码如下:
这题其实和斐波那契数列异曲同工,第i层只能由第i-1和i-2层得到,所以我们获得状态转移方程 dp[i] = dp[i-1] + dp[i-2] 得解 3.爬楼梯最小花费 给定一个n(n<=1000),再给定一个n个整数的数组cost, 其中cost[i]是从楼梯第i个 台阶向上爬需要支付的费用。一旦支付此费用,即可选择向上爬一个或者两个台阶。 可以选择从下标为0或下标为1的台阶开始爬楼梯,请计算并返回达到楼梯顶部的最低花费。 代码如下:
要求最小花费,那就是求从哪种状态来的花费最小,得到状态转移方程 dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]) 得解 4.删除并获得点数 给你一个整数数组 nums ,你可以对它进行一些操作。 每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除每个等于 nums[i] - 1 或 nums[i] + 1 的元素。 开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。 代码如下:
有些同学可能开始懵逼了,别急,先看下一题获得思路: 5.打家劫舍 给定一个整数n(1<=n<=100),再给定一个n个整数的数组nums,每个整数可以选择取或者不取,如果第i个整数取,那么 第i-1或者i+1个整数就不能取。 要求按照上述规则选取一些整数,使得选出来的整数得到的总和最大,返回这个最大值。 代码如下:
这个题目要求我们相邻的数不能选,并求出最大的总和,我们假设dp[i]就是前i个数最大总和,则dp[i]只能由dp[i-1] 和之前的dp[i-2]得到,如果是前者则不能添加第i个数,如果是后者则可以将第i个数加入,得到状态转移方程: dp[i] = max(dp[i-1],dp[i-2]+nums[i]) 得解。 看到这里,第四题已经很明了了,题目要求删除nums[i]+1或nums[i]-1的值,那我们直接将原有数组排序,按照打家劫舍问题求解即可 6.最大子数组和 给定一个整数n(1<=n<=10**5),再给定一个n个整数的数组nums,请找出一个具有 最大和的连续子数组,返回其最大和。 代码如下:
我们假设dp[i]为前i个数字所组成数组中的最大连续数组,可得状态转移方程: dp[i] = max(nums[i-1],(dp[i-1]+nums[i-1)) 得解 7.整数拆分 给定?个正整数 n,将其拆分为?少两个正整数的和,并使这些整数的乘积最?化。返回 你可以获得的最?乘积。 代码如下:
本题也有其规律,多次测试会发现最优解为,n个3和0或一个4相乘,比如10等于3*3*4 9等于3*3*3 8等于3*3*2,根据规律运用贪心可将时间复杂度进一步降低 8.不同路径 ????????相信同学们对创建一维数组解决问题已经了如指掌,可是实际问题可能要考虑更多的变量: ?个机器?位于?个 m x n ?格的左上?(起始点在下图中标记为 “Start” )。 机器?每次只能向下或者向右移动?步。机器?试图达到?格的右下?(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 代码如下:
有草稿纸的同学请画出表格,机器人从(0,0)到(m-1,n-1),我们假设移动到一格的路径有dp[i][j]种,由于机器人只能向右或向下移动,那么dp[i][j]只能由dp[i-1][j]和dp[i][j-1]得到,状态转移方程: dp[i][j] = dp[i-1][j] + dp[i][j-1] 得解 9.01背包问题 有N件物品和?个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是 value[i] 。每件物品只能??次,求解将哪些物品装?背包?物品价值总和最?。 物品0 重量1 价值15,物品1 重量3 价值20,物品2 重量4 价值30 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]) # 从下标为[0-i]的物品?任意取,放进容量为j的背包,价值总和 最?是多少
有草稿纸同学一定要画表格,n*w的表格,n代表物品,w代表背包重量,那么对于第i件物品dp[i][j]选不选就是问题的核心,得到状态转移方程: dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]) 得解 10.完全背包问题 代码如下:
完全背包问题与01背包问题的区别在于一件物品是否可以多次选取,如果你已经理解完全背包问题和01背包问题,试着结合两者解决多重背包问题 11.滚动数组 ? ? ? ? 我们发现使用多维数组十分地占用空间,有没有一种办法将其降维呢?那就是使用滚动数组: 代码如下:
关于背包问题,上文我们定义i为物品,j为背包重量,但我们可不可以当用j来表示呢?dp[j]表示背包承重为j时装入的最大价值,得到状态转移方程: dp[j] = max(dp[j],dp[j-weight[i]+value[i]) 得解。 看到这里,你对动态规划已经基本入门,获取知识的最好方法是解决问题,赶紧趁热刷题吧,想必你会有新收获! |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 19:31:34- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |