动态规划(0-1背包问题)python版本

本文介绍了动态规划在解决0-1背包问题中的应用,详细阐述了问题背景、动态规划的原理,并提供了使用Python实现的代码。在复盘部分,作者讨论了初始化二维数组时的常见陷阱,推荐使用numpy创建二维数组以避免数据共享问题。最终,作者将运算结果转换为DataFrame并保存到Excel文件。
摘要由CSDN通过智能技术生成

  动态规划就是将问题划分为子问题,通过子问题的最优解得到原问题的最优解。动态规划把每个求解过程的子问题记录下来,下次碰到同样的子问题可以直接使用之前的结果。下面学习一类经典的背包问题。

1.背包问题

问题是这样的:n 件物品,每个重量 w[i],价值 c[i] 。背包容量 V。问如何使得背包内物品总价值最大。每种物品只有一件。

定义 dp[i][j] 表示前 i 件物品装入容量 j 的背包的价值,那么:

dp[i][j] = Math.max(
 dp[i-1][j],  // 不放第 i 件物品
    dp[i-1][j-w[i]] + c[i] // 放第 i 件物品
) 

因此代码如下:

for (int i = 0; i < n; i++) {
    for (int j = w[i]; j <= V; j++) {
        dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i]] + c[i]);
    }
}
  1. 整体代码如下
"""
N=4,V=10
w1 = 8, c1 = 9
w2 = 3, c2 = 3
w3 = 4, c3 = 4
w4 = 3, c4 = 3

通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,
用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。

定义dp[i][j]为前i件物品装入容量为j的的背包的价值,即每放进一个物品就要
牺牲背包二点容量来获取背包的总价值
"""
import numpy as np
c=[0,9,3,4,3]
w=[0,8,3,4,3]
N=4
V=10

def 背包问题(N,w,c,V):
    #既然是将物品放到背包,那么是以物品为主题,首先进行第一层循环,用w[i]可以遍历上一层的每一个商品的重量
    dp = np.zeros((N+1, V+1), dtype=np.int32)
    for i in range(1,N+1,1):
        #然后再来第二层循环,j表示容量,j的最大值为容量V,最小值为必须大于当前遍历的物品的重量
        for j in range(1,V+1,1):   #这里出现一个问题:为什么每次要递减一,因为重量的最小单位就是1呀哈哈
            if(j<w[i]):
                dp[i,j]=dp[i-1,j]    #如果说当前要装入的物品的重量大于背包的容量,直接返回未装之前背包的价值
            else:                       #否则,我们挑选最大值未转这个物品之前背包的价值 和 装了之后背包的价值
                dp[i,j]=max(dp[i-1,j],dp[i-1,j-w[i]]+c[i])
    return dp

a=背包问题(N,w,c,V)
print(a)

2.复盘

在初始化一个dp二位数组的时候,应该注意到创建数组有三种办法

1.

a=[[]*11]*5
a[0].append(1)
print(a)

2.

b=[[] for j in range(5)]
for j in
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值