完全背包

完全背包

问题描述

个物品,每个物品有重量 和价值 。现在有一个容量为 的背包,每个物品可以选择任意次(无限次),求解在不超过背包容量的情况下,能够装入物品的最大价值。

与01背包的区别

  1. 01背包:每个物品最多选择一次
  2. 完全背包:每个物品可以选择无限次

动态规划解法

状态定义

  • 表示考虑前 个物品,背包容量为 时能获得的最大价值

状态转移方程

dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]] + v[i])  if j >= w[i]
dp[i][j] = dp[i-1][j]                              if j < w[i]

注意:与01背包的区别是 而不是

代码实现

C++ 实现(二维)

int completeKnapsack(vector<int>& w, vector<int>& v, int W) {
    int n = w.size();
    vector<vector<int>> dp(n + 1, vector<int>(W + 1, 0));
    
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= W; j++) {
            if (j >= w[i-1]) {
                dp[i][j] = max(dp[i-1][j], dp[i][j-w[i-1]] + v[i-1]);
            } else {
                dp[i][j] = dp[i-1][j];
            }
        }
    }
    
    return dp[n][W];
}

C++ 实现(一维优化)

int completeKnapsack(vector<int>& w, vector<int>& v, int W) {
    int n = w.size();
    vector<int> dp(W + 1, 0);
    
    for (int i = 0; i < n; i++) {
        for (int j = w[i]; j <= W; j++) {
            dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
        }
    }
    
    return dp[W];
}

Java 实现

class Solution {
    public int completeKnapsack(int[] w, int[] v, int W) {
        int n = w.length;
        int[] dp = new int[W + 1];
        
        for (int i = 0; i < n; i++) {
            for (int j = w[i]; j <= W; j++) {
                dp[j] = Math.max(dp[j], dp[j-w[i]] + v[i]);
            }
        }
        
        return dp[W];
    }
}

Python 实现

def completeKnapsack(w: List[int], v: List[int], W: int) -> int:
    n = len(w)
    dp = [0] * (W + 1)
    
    for i in range(n):
        for j in range(w[i], W + 1):
            dp[j] = max(dp[j], dp[j-w[i]] + v[i])
    
    return dp[W]

与01背包的代码区别

  1. 状态转移时使用当前行的状态
  2. 容量的遍历方向改为正序
  3. 可以直接从物品重量开始遍历

时间复杂度分析

  • 时间复杂度:
  • 空间复杂度:
    • 二维实现:
    • 一维实现:

常见变形

  1. 求恰好装满背包的最大价值
  2. 求最少需要多少个物品装满背包
  3. 求装满背包的方案数
  4. 求满足条件的最小代价

应用场景

  1. 零钱兑换问题
  2. 物资补给规划
  3. 资源重复利用
  4. 生产计划制定
  5. 库存补货策略

注意事项

  1. 遍历顺序的区别
  2. 状态转移的依赖关系
  3. 初始化的处理
  4. 特殊情况的考虑
  5. 数据范围的限制

经典例题

  1. 【模板】完全背包
  2. 最少的完全平方数
  3. 兑换零钱
牛客代码笔记-牛栋 文章被收录于专栏

汗牛充栋,学海无涯。<br/> 内含算法知识点讲解,以及牛客题库精选例题。<br/> 学习算法,从牛栋开始。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务