完全背包(动态规划)

96 篇文章 2 订阅
24 篇文章 0 订阅

1. 问题描述:

有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。第 i 种物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0 < N,V ≤ 1000
0 < vi,wi ≤ 1000

输入样例

4 5
1 2
2 4
3 4
4 5

输出样例:

10

来源:https://www.acwing.com/problem/content/3/

2. 思路分析:

这道题目属于完全背包的裸题(模板题),直接使用完全背包的模板即可解决,为了节省空间我们可以使用一维的动态规划解决,其实完全背包问题与01背包问题是类似的,只是完全背包问题拿取的每个物品都是无限的。在递推的过程中一维的01背包第二层循环是逆序遍历背包的容量,逆序遍历的目的是为了保证之前拿取的每一个物品是只拿取过0次或者是1次的,而完全背包恰恰相反我们需要保证之前拿取的物品是有若干次的,所以在正序遍历背包容量的时候实际上是在尝试1 * v[i],2 *v[i]...k * v[i],这样表示的是在背包最大容量的前提下允许拿取当前物品有k次,并且在拿取物品的时候是递推得到当前背包容量的前提下能够拿取物品的最大价值。其实可以结合01背包问题的代码进行记忆,完全背包问题是正序遍历背包容量,01背包是逆序遍历背包容量。

3. 代码如下:

if __name__ == '__main__':
    n, v = map(int, input().split())
    vi, wi = list(), list()
    for i in range(n):
        a, b = map(int, input().split())
        vi.append(a)
        wi.append(b)
    dp = [0] * (v + 1)
    # 正序遍历
    for i in range(n):
        for j in range(vi[i], v + 1):
            dp[j] = max(dp[j], dp[j - vi[i]] + wi[i])
    print(dp[-1])
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值