由于本人的算法基础较为薄弱,所以在这里整理一下自己的做过的题,使自己能够随时随地回顾温习。
然后,本篇文章将会持续更新自己遇到的一些比较经典动态规划的题目,大家如果对代码有任何问题,直接在文章下面评论即可。我看到后会立刻回复。
1.我对动态规划的理解
网上对动态规划的介绍的文章已经很多了,那这里我还是要谈一下自己的理解,希望能够给大家带来一些灵感。
我所理解的动态规划,就两个词:动态、规划。动态我自己理解为:一个问题可以拆分为若干个子问题,然后通过逐步递推,得到最终的结果。规划就是最优问题,整体的最优细分到每个递推环节的最优。
然后,解决动态规划问题,最重要的可以发现其中的状态转移方程,我理解的状态转移方程的意思就是:一个通用的方程,即任意中间一个状态能够由前面的状态所推导得到。比如下图的dp[i][j]状态,就可以由左上的3个状态推导得到。
很多动态规划的问题,具体解法大多都是通过一个二维数组来存储中间环节的最优解。最后求二维数组中的最大值或者最后一个值。还有一种情况就是:如果当前状态只跟前面的一个状态有关,那么二维数组是可以优化为一维数组的,这样空间复杂度就由O(n2)优化为O(n)了。
2.例题整理
2.1 经典01背包问题
题目描述:一个人去偷东西,他的背包容量最大为20kg,然后有重量、价值不等的物品,比如重量为2、价值为3的物品,每件物品只能拿一件,求小偷能偷到的物品最大的价值。
"""
物品重量与价值对应关系:
w v
2 3
3 4
5 8
9 10
背包容量:20
"""
import numpy as np
def func(pack, cap):
max_value_arr = np.zeros([len(pack)+1, cap+1])
# 第一列与第一排全为0,这样为后续能递推max_value_arr的值
max_value_arr[:,0] = 0
max_value_arr[0,:] = 0
# i代表pack物品的序号
for i in range(1, len(pack)+1):
# j代表包中