Datawhale编程——动态规划DP
0-1背包问题
问题:有n个物品,第i个物品价值为vi,重量为wi,其中vi和wi均为非负数,背包的容量为W,W为非负数。现需要考虑如何选择装入背包的物品,使装入背包的物品总价值最大。
针对这个经典的动态规划问题,先建立一个实例,如下表格:
物体编号i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
价值v | 4 | 5 | 10 | 11 | 13 |
重量w | 3 | 4 | 7 | 8 | 9 |
假设约束条件背包的最大承重\(W = 17\),且每个物体只能装一次,请问背包应该怎么装最好。
这一类问题依旧是两个关键:1.初始条件或者最小子问题最优解;2.递归定义式或状态转移方程。
这里最小子问题最优解应该就是,背包只选一个物品且在限定承重 W' 时所指向的最佳物体。这里 W' 可以为大于等于1的任意值。
那么状态转移方程应该就是,在当前给定限定承重条件下,从不同的承重组合选出一个最优解(每一个都是它在限定承重条件下得到的最优解)。用数学定义式可以如下:
\[ dp[i][j] = max(dp[i-1][j], dp[i-1][j-w(k)]+v[k]) \]
其中dp[i][j]表示i件物品放入一个容量为j的背包可以获得的最大价值。这个式子不是很好理解,举个例子就很清楚了,如下。
比如当前背包容量是10,那我们可以有多种分配组合,比如9+1,以及7+3。其中dp[i-1][j]可以对应分配的9,dp[i-1][j-w(k)]可以对应分配的7;左边9所对应的1是再找不出适合装的东西了,右边7对应的3可以再装一个编号1。这个式子的意义就是,比较这两种组合其中的更佳者。
需要注意的是,不一定永远是右边的更佳,有时候空间不全部利用反而能得到更加解。这就是动态规划的关键。
要是直接将动态规划的代码写出来,有时候可能很困难。可以先考虑用递归做,再将自顶向下的递归转化为自底向上的动态规划就好了。这里就不管这些,直接给出动态规划的代码了。
class ZeroByOnePack:def __init__(self, list_v, list_w):self.list_v = list_vself.list_w = list_wdef dpPack(n, max_w):V = self.list_vW = self.list_wdp = [0] * (max_w + 1) # 为了形式上好理解,只好浪费一部分空间for i in range(n);for j in range(W[i], max_w + 1):dp[j] = max(dp[j], dp[j-W[i]]+V[i])return dp[max_w]
这里只用一维数组,节省内存空间。
leetcode 132
代码实现
作业限制了用动态规划,但其实这道题不用动态规划也可以做。
class Solution(object):def minCut(self, s):""":type s: str:rtype: int"""cut = [x for x in range(-1,len(s))]for i in range(0,len(s)):for j in range(i,len(s)):if s[i:j] == s[j:i:-1]:cut[j+1] = min(cut[j+1],cut[i]+1)return cut[-1]
当然,这个性能是很差的,时间复杂度应该达到了O(n^3)?如果用动态规划的话,时间复杂度只要O(n^2)。
class Solution:def minCut(self, s):""":type s: str:rtype: intThis can be solved by:cut[end] is the minimum of cut[st-1] + 1 (st <= end) if [st, end] is palindromea b a | c cst endst-1 | [st, end] is palindromecut(st-1) + 1"""n = len(s)cut = [0] * npal = [[False] * n for row in range(n)]for end in range(n):min_cut = endfor st in range(end + 1):if s[st] == s[end] and (end - st <= 2 or pal[st+1][end-1]):pal[st][end] = Truemin_cut = 0 if st == 0 else min(min_cut, cut[st-1] + 1)cut[end] = min_cutreturn cut[n-1]
代码不是自己写的。我只能根据简单的思路写出递归的算法,但是这道题卡了递归的边界。也许将递归算法改进成备忘录方法会更好点,这个留待以后验证了。
转载于:https://www.cnblogs.com/ChanWunsam/p/10246615.html
Datawhale编程——动态规划DP相关推荐
- 第4课 防卫导弹(第十章 动态规划--DP)
//progream p10_04 /* 第4课 防卫导弹(第十章 动态规划--DP) (<聪明人的游戏--信息学探秘 提高篇>) https://blog.csdn.net/weixi ...
- 动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包,混合背包
动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包 01背包 && 完全背包 && 分组背包 の 视频教程:https://www.bilibi ...
- 【习题详解】动态规划DP:硬币游戏 蛋糕 游荡的奶牛 决斗
动态规划DP 硬币 蛋糕塔 游荡的奶牛 格斗 硬币 题目描述 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为"Xoinc"的两人硬币游戏. 初始时,一个有N(5 <= N ...
- 动态规划: dp+递推——确定动态矩阵dp含义,确定每个状态下面临的选择和对结果值影响,选择符合题意的作为结果存储在dp中
1.动态规划:每一个状态一定是由之前的状态推导出来的,通过总结归纳发现递推关系 2.解决动态规划问题的步骤: 确定dp数组(dp table)以及下标的含义: 每个单元内 题目所求的值,一维.二维 确 ...
- 动态规划(dp)总结
问题 T: [动态规划]质数和分解 题目描述 任何大于1的自然数n,都可以写成若干个大于等于2且小于等于n的质数之和的形式(包括只有一个数构成的和表达式的情况),并且可能有不止一种质数和的形式.例如9 ...
- dp 扔鸡蛋_使用动态编程(DP)的鸡蛋掉落问题
dp 扔鸡蛋 Problem statement: You are given N floor and K eggs. You have to minimize the number of times ...
- 编辑距离 dp_使用动态编程(DP)编辑距离
编辑距离 dp Problem: You are given two strings s1 and s2 of length M and N respectively. You can perform ...
- 《强化学习》中的 时序差分学习 Temporal-Difference Learning (基于与动态规划 DP 、蒙特卡洛方法 MC 的对比)
前言: 学习了 Sutton 的<强化学习(第二版)>中时序差分学习的"预测"部分内容.前两章中,书介绍了 动态规划 与 蒙特卡洛方法 ,我们从二者与 时序差分学习 的 ...
- HDU2571 命运【动态规划DP】
命运 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
最新文章
- Python培训中有哪些是必须学的运算符
- 手把手教你从系统层面优化深度学习计算
- 字符串与byte[]之间的转换
- mybatis TypeHandler 类型处理器
- Principle for Mac:让你五分钟即可制作出一个具有完整交互动画的原型
- 大厂在用的Python反爬虫手段,破了它!
- timestamp显示毫秒_mysql解决datetime与timestamp精确到毫秒的问题
- 从400+节点ElasticSearch集群的运维中,我们总结了这些经验
- 设计模式:高性能IO之Reactor模式
- 第2章[2.7] Ext JS数据模型与数据封装
- Go各种类型转换及函数的高级用法
- python调试代码举例
- SQL语句处理一些修改、新增、删除、修改属性操作(MySql)
- 商城购物车php代码,php网上商城购物车设计代码
- 安国U盘量产后USB损坏恢复工具for win7
- 计算机excel还原,Excel文件恢复软件(Magic Excel Recovery)
- Snipaste安装教程及软件(截图工具)
- AccessController的doPrivileged使用
- THREE 使用Tween插件实现动画
- Blos查看计算机硬盘,bios查看硬盘损坏