0/1背包与完全背包差异分析

ops/2024/10/20 20:57:03/

文章目录

  • 定义差异分析
  • 代码实现分析
  • 总结

定义差异分析

  1. 0/1背包问题:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
  2. 完全背包问题: 有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],价值是value[i] 。每件物品可以放入背包多次,求解将哪些物品装入背包里物品价值总和最大。

对于每一件物品,0/1背包问题是放和不放的问题,完全背包是,放多少件的问题(可以是0)

代码实现分析

为了易于理解,这里的代码没有使用滚动数组(dp数组压缩成一维)

/*** 0/1背包问题:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],价值是value[i] 。*      每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。* @param weights weight[i]第i件物品的重量* @param values value[i]第i件物品的价值* @param n 物品数量* @param w 背包容量* @return 最大价值*/
int zeroOneBackpack(int weights[], int values[], int n, int w) {// 1. dp[i][j] 从前i中材料中任选,装满容量为j的背包,最大的价值int dp[][] = new int[n][w + 1];/*2. 递推公式 根据是否放入物品i分两种情况1)不放入物品i,那么dp[i][j] = dp[i - 1][j]也就是从前i - 1中材料中任选,装满容量为j的背包,最大的价值2)放入物品i,那么dp[i][j] = values[i] + dp[i - 1][j - weights[i]]也就是放入物品i后,剩余的空间为j - weights[i]从i - 1中材料中任选,装满容量为j - weights[i]的背包,最大的价值为dp[i - 1][j - weights[i]]dp[i][j]为两个之和,即values[i] + dp[i - 1][j - weights[i]]3)如果容量j小于物品i的重量weight[i],那么就不需要考虑第二种情况dp[i][j] = dp[i - 1][j];if (j >= weights[i])dp[i][j] = max(dp[i][j], values[i] + dp[i - 1][j - weights[i]])*/// 3. 初始化for (int j = weights[0]; j <= n; j ++) {dp[0][j] = values[0];}// 4. 递推顺序for (int i = 1; i < n; i ++) {for (int j = 1; j <= n; j ++) {dp[i][j] = dp[i - 1][j];if (j >= weights[i]) {dp[i][j] = max(dp[i][j], values[i] + dp[i - 1][j - weights[i]]);}}}return dp[n - 1][w];
}
/*** 完全背包问题:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],价值是value[i] 。*      每件物品可以选多次(包含0),求解将哪些物品装入背包里物品价值总和最大。* @param weights weight[i]第i件物品的重量* @param values value[i]第i件物品的价值* @param n 物品数量* @param w 背包容量* @return 最大价值*/
int completeBackpack(int weights[], int values[], int n, int w) {// 1. dp[i][j] 从物品0-i中任取,每个物品能取无限次//    装满容量为j的背包,能获取的最大价值int dp[][] = new int[n][w + 1];/*2. 递推公式 根据是否放入物品i分两种情况1)不放入物品i,那么dp[i][j] = dp[i - 1][j]也就是从前i - 1中材料中任选,装满容量为j的背包,最大的价值2)放入物品i,那么dp[i][j] = values[i] + dp[i - 1][j - weights[i]]也就是放入物品i后,剩余的空间为j - weights[i]再从i中材料中任选,装满容量为j - weights[i]的背包,最大的价值为dp[i][j - weights[i]]dp[i][j]为两个之和,即values[i] + dp[i][j - weights[i]]3)如果容量j小于物品i的重量weight[i],那么就不需要考虑第二种情况dp[i][j] = dp[i - 1][j];if (j >= weights[i])dp[i][j] = max(dp[i][j], values[i] + dp[i][j - weights[i]])*/// 3. 初始化for (int j = 0; j <= w; j ++) {// 背包能放多少个物品0 (j / weights[0])dp[0][j] = (j / weights[0]) * values[0];}// 4. 递归顺序for (int i = 1; i < n; i++) {for (int j = 0; j <= w; j++) {dp[i][j] = dp[i - 1][j];if (j >= weights[i]) {// dp[i][j] = max(dp[i][j], values[i] + dp[i - 1][j - weights[i]]);// 上一行注释是0/1背包的递推公式// 0/1背包是values[i] + dp[i - 1][j - weights[i]]// 完全背包是values[i] + dp[i][j - weights[i]]// 0/1背包,如果我放入物品i,剩余的容量为j - weights[i]//		因为物品i已经放入了,那么我需要找的是从物品0 ~ i-1中任选,能获取的最大价值//		所以是dp[i - 1][j - weights[i]]// 完全背包,如果我放入物品i,剩余的容量为j - weights[i]//		此时放入了物品i,但因为每一件物品可以放入多次,那么我需要找的是,//		从物品0 ~ i中任选,能获取的最大价值,也就是dp[i][j - weights[i]]// 综上,0/1背包与完全背包在于我放入物品i后,剩余的容量能放的物品分别为[0, i-1]和[0, i]dp[i][j] = max(dp[i][j], values[i] + dp[i][j - weights[i]]);}}}return dp[n - 1][w];
}

总结

  1. dp数组定义:dp[i][j]从物品0-i中任取,装满容量为j的背包,能获取的最大价值
  2. 0/1背包,放入了物品i后,剩余的容量只能放物品[0, i - 1];完全背包,放入了物品i后,剩余的容量能放物品[0, i],也就是物品i能够重复放入。
  3. 携带研究材料 - 0/1背包问题
  4. 携带研究材料 - 完全背包问题

http://www.ppmy.cn/ops/121882.html

相关文章

记一次控件提升后,运行却不显示的Bug

.h文件 #ifndef VOLUMETOOLBTN_H #define VOLUMETOOLBTN_H#include <QToolButton> #include <memory>class VolumeToolBtn : public QToolButton { Q_OBJECTpublic:explicit VolumeToolBtn(QWidget *parent nullptr);~VolumeToolBtn() override;void initUi(); p…

netty之基础aio,bio,nio

前言 在Java中&#xff0c;提供了一些关于使用IO的API&#xff0c;可以供开发者来读写外部数据和文件&#xff0c;我们称这些API为Java IO。IO是Java中比较重要知识点&#xff0c;且比较难学习的知识点。并且随着Java的发展为提供更好的数据传输性能&#xff0c;目前有三种IO共…

基于深度学习的手势控制模型

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

golang grpc初体验

grpc 是一个高性能、开源和通用的 RPC 框架&#xff0c;面向服务端和移动端&#xff0c;基于 HTTP/2 设计。目前支持c、java和go&#xff0c;分别是grpc、grpc-java、grpc-go&#xff0c;目前c版本支持c、c、node.js、ruby、python、objective-c、php和c#。grpc官网 grpc-go P…

vulnhub-digitalworld.local DEVELOPMENT靶机

vulnhub&#xff1a;digitalworld.local: DEVELOPMENT ~ VulnHub 导入靶机&#xff0c;放在kali同网段&#xff0c;扫描 靶机在192.168.114.129&#xff0c;扫描端口 开了几个端口&#xff0c;8080端口有网页&#xff0c;访问 说是让访问html_pages 似乎把页面都写出来了&…

ConcurrentHashMap在JDK1.7和1.8的区别,详解

目录 1.了解HashMap底层插入原理 2.ConcurrentHashMap 是什么&#xff1f; HashTable的实现 3.ConcurrentHashMap 1.7和1.8的区别 4、JDK1.7 中的ConcurrentHashMap实现原理 6、JDK1.8中的ConcurrentHashMap 7.链表转红黑树条件 1.8 put方法 8.并发扩容 9.总结 首先呢…

记HttpURLConnection下载图片

目录 一、示例代码1 二、示例代码2 一、示例代码1 import java.io.*; import java.net.HttpURLConnection; import java.net.URL;public class Test {/*** 下载图片*/public void getNetImg() {InputStream inStream null;FileOutputStream fOutStream null;try {// URL 统…

前端编程艺术(4)---JavaScript进阶(vue前置知识)

目录 1.变量和常量 2.模版字符串 3.对象 4.解构赋值 1.数组的解构 2.对象的解构 5.箭头函数 6.数组和对象的方法 7.扩展运算符 8.Web存储 9.Promise 10.AsyncAwait 11.模块化 1.变量和常量 JavaScript 中的变量和常量是用于存储数据的标识符。变量可以被重新赋值&am…