完全背包(模板)

一、题目描述

描述

你有一个背包,最多能容纳的体积是V。

现在有n种物品,每种物品有任意多个,第i种物品的体积为vi​ ,价值为wi​。

(1)求这个背包至多能装多大价值的物品?

(2)若背包恰好装满,求至多能装多大价值的物品?

输入描述:

第一行两个整数n和V,表示物品个数和背包体积。

接下来n行,每行两个数vi和wi,表示第i种物品的体积和价值。

1≤n,V≤10001≤n,V≤1000

输出描述:

输出有两行,第一行输出第一问的答案,第二行输出第二问的答案,如果无解请输出0。

示例1

输入:

2 6
5 10
3 1
输出:
10
2

示例2

输入:

3 8
3 10
9 1
10 1
输出:
20
0

说明:

无法恰好装满背包。

示例3

输入:

6 13
13 189
17 360
19 870
14 184
6 298
16 242
输出:
596
189

说明:

可以装5号物品2个,达到最大价值298*2=596,若要求恰好装满,只能装1个1号物品,价值为189.

题目链接:

【模板】完全背包_牛客题霸_牛客网 

二、 解题方法(动态规划)

先解决第一问:
1、状态表示
dp[i][j] 表示:从前 i 个物品中挑选,总体积不超过 j ,所有的选法中,能挑选出来的最大价值。
2、状态转移方程
我们根据最后一步的状况,来分情况讨论。但是最后一个 物品能选很多个,因此我们的需要分很多情况:
(1) 选 0 个第 i 个物品 :此时相当于就是去前 i - 1 个物品中挑选,总体积不超过 j
此时 最大价值为 dp[i - 1][j] ;
(2) 选 1 个第 i 个物品 :此时相当于就是去前 i - 1 个物品中挑选,总体积不超过 j - v[i] 。因为挑选了一个 i 物品,此时 最大价值为 dp[i - 1][j - v[i]] + w[i];
(3) 选 2 个第 i 个物品 :此时相当于就是去前 i - 1 个物品中挑选,总体积不超过 j - 2 * v[i] 。因为挑选了两个 i 物品,此时 最大价值为 dp[i - 1][j - 2 * v[i]] + 2 * w[i] ;
(4)......
综上,我们的状态转移方程为:
dp[i][j]=max(dp[i-1][j], dp[i-1][j-v[i]]+w[i], dp[i-1][j-2*v[i]]+2*w[i]...)
此时,可以进行优化,优化的方 向就是用一个或者两个状态来表示这一堆的状态,通常就是用数学的方式做一下等价替换。
我们发 第二维是有规律的变化的,因此我们去看看 dp[i][j - v[i]] 这个状态:
dp[i][j-v[i]]=max(dp[i-1][j-v[i]],dp[i-1][j-2*v[i]]+w[i],dp[i-1][j-3*v[i]]+2*w[i]...)
我们发现, 把 dp[i][j - v[i]] 加上 w[i] 正好和 dp[i][j] 中除了第一项以外的全部一致 ,因此我们可以修改我们的状态转移方程为:
dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i])
3、初始化
我们多加一行,方便我们的初始化,此时 仅需将第一行初始化为 0 即可 。因为什么也不选,也能
满足体积不大于 j 的情况,此时的价值为 0
4、填表顺序
根据状态转移方程, 仅需从上往下填表即可。
5、返回值
根据状态表示,返回 dp[n][V]
接下来解决第二问:
因为有可能凑不齐 j 体积的物品,因此我们把不合法的状态设置为 -1 。
1、状态表示
dp[i][j] 表示:从前 i 个物品中挑选,总体积正好等于 j ,所有的选法中,能挑选出来的最大价值。
 
2、状态转移方程
dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i]) 。
但是在使用 dp[i][j - v[i]] 的时候,不仅要判断 j >= v[i] ,又要判断 dp[i][j - v[i]] 表示的情况是否存在,也就是 dp[i][j - v[i]] != -1 。
3、初始化
我们多加一行,方便我们的初始化:
1) 第一个格子为 0 ,因为正好能凑齐体积为 0 的背包;
2) 但是第一行后面的格子都是 -1 ,因为没有物品,无法满足体积大于 0 的情况。
4、填表顺序
仅需从上往下填表即可。
5、返回值
由于最后可能凑不成体积为 V 的情况,因此返回之前需要判断一下。 

三、代码

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//输入n,Vint n = in.nextInt();int V = in.nextInt();//创建v,w数组,存每个物品的体积、价值int[] v = new int[n+1];int[] w = new int[n+1];//接下来输入n行,每行两个数vi​和wifor (int i = 1; i <= n; i++) {v[i] = in.nextInt();w[i] = in.nextInt();}//创建dp数组int[][] dp = new int[n + 1][V + 1];//初始化for (int j = 0; j <= V; j++) {dp[0][j] = 0;}//填表for (int i = 1; i <= n; i++) {for (int j = 0; j <= V; j++) {dp[i][j] = dp[i - 1][j];if (j >= v[i]) {dp[i][j] = Math.max(dp[i][j], dp[i][j - v[i]] + w[i]);}}}System.out.println(dp[n][V]);//将dp表清零,继续求解第二问for (int i = 0; i <= n; i++) {for (int j = 0; j <= V; j++) {dp[i][j] = 0;}}//初始化dp表for (int j = 1; j <= V; j++) {dp[0][j] = -1;}//填表for (int i = 1; i <= n; i++) {for (int j = 0; j <= V; j++) {dp[i][j] = dp[i - 1][j];if (j >= v[i] && dp[i][j-v[i]] != -1) {dp[i][j] = Math.max(dp[i][j], dp[i][j - v[i]] + w[i]);}}}//要判断一下,是否存在能将背包装满的情况System.out.println(dp[n][V] == -1 ? 0 : dp[n][V]);}
}

四、空间优化

 代码:

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//输入n,Vint n = in.nextInt();int V = in.nextInt();//创建v,w数组,存每个物品的体积、价值int[] v = new int[n+1];int[] w = new int[n+1];//接下来输入n行,每行两个数vi​和wifor (int i = 1; i <= n; i++) {v[i] = in.nextInt();w[i] = in.nextInt();}//创建dp数组int[] dp = new int[V + 1];//初始化for (int j = 0; j <= V; j++) {dp[j] = 0;}//填表for (int i = 1; i <= n; i++) {for (int j = v[i]; j <= V; j++) {dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);}}System.out.println(dp[V]);//将dp表清零,继续求解第二问for (int j = 0; j <= V; j++) {dp[j] = 0;}//初始化dp表for (int j = 1; j <= V; j++) {dp[j] = -1;}//填表for (int i = 1; i <= n; i++) {for (int j = v[i]; j <= V; j++) {if (dp[j-v[i]] != -1) {dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);}}}System.out.println(dp[V] == -1 ? 0 : dp[V]);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/857299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

客户端如何验证服务器SSL证书的有效性?

目录 1. 证书链验证2. 证书有效期3. 证书吊销状态4. 证书的域名匹配5. 证书的签名验证6. 证书的公钥用途 1. 证书链验证 证书链完整性 证书链通常由服务器证书、中间证书和根证书组成。客户端需要验证从服务器证书到受信任的根证书之间的所有中间证书。每个证书都必须正确地链…

PyTorch下的5种不同神经网络-ResNet

1.导入模块 导入所需的Python库&#xff0c;包括图像处理、深度学习模型和数据加载 import osimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import Dataset, DataLoaderfrom PIL import Imagefrom torchvision import models, transf…

Interpreting Machine Learning Models with SHAP: A Comprehensive Guide

Interpreting Machine Learning Models with SHAP: A Comprehensive Guide DateAuthorVersionNote2024.06.20Dog TaoV1.0Finish the document. 文章目录 Interpreting Machine Learning Models with SHAP: A Comprehensive GuideWhat is SHAPUnderstanding Base ValueDefiniti…

虚拟机拖拽文档造成缓存过大

查看文件夹大小&#xff1a;du -h --max-depth1 缓存位置&#xff1a;~/.cache/vmware/drag_and_drop 删除&#xff1a;rm -fr ~/.cache/vmware/drag_and_drop 释放了3GB

自然语言NLP的基础处理

NLP基本处理从句子的情感分析、实体与实体直接的关系&#xff0c;句子结构来分析 情感分析 1.句子的情感分析找出句子表达的是正面、负面还是中性的情感。 情感分析的影响因素&#xff1a; 词语顺序&#xff1a;词语的顺序可以影响句子的整体情感。例如&#xff0c;“我喜欢…

网络安全:Web 安全 面试题.(文件上传漏洞)

网络安全&#xff1a;Web 安全 面试题.&#xff08;文件上传漏洞&#xff09; 网络安全面试是指在招聘过程中,面试官会针对应聘者的网络安全相关知识和技能进行评估和考察。这种面试通常包括以下几个方面&#xff1a; &#xff08;1&#xff09;基础知识:包括网络基础知识、操…

CVPR上新 | 从新视角合成、视频编解码器、人体姿态估计,到文本布局分析,微软亚洲研究院精选论文

编者按&#xff1a;欢迎阅读“科研上新”栏目&#xff01;“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里&#xff0c;你可以快速浏览研究院的亮点资讯&#xff0c;保持对前沿领域的敏锐嗅觉&#xff0c;同时也能找到先进实用的开源工具。 本周&#xff0…

python如何判断图片是否为空

如下所示&#xff1a; import cv2im cv2.imread(2.jpg) if im is None:print("图像为空") # cv2.imshow("ss", im) # cv2.waitKey(0)

编码规则UTF-8 和 UTF-16的区别

UTF-8 和 UTF-16 的设计背景与历史 为了更好地理解 UTF-8 和 UTF-16 的设计选择和背景&#xff0c;以下是两种编码方案的历史、设计动机和它们在计算机科学中的应用。 Unicode 的背景 在 Unicode 之前&#xff0c;不同的字符集和编码方案使得跨平台和国际化的文本处理变得复…

2024年AI+游戏赛道的公司和工具归类总结

随着人工智能技术的飞速发展,AI在游戏开发领域的应用越来越广泛。以下是对2024年AI+游戏赛道的公司和工具的归类总结,涵盖了从角色和场景设计到音频制作,再到动作捕捉和动画生成等多个方面。 2D与3D创作 2D创作工具:专注于角色和场景的平面设计,提供AI辅助的图案生成和风…

C++之thread_local变量

目录 1.C 的存储类型 1.1.存储周期&#xff08;Storage duration&#xff09; 1.2.存储类型说明符&#xff08;Storage class specifiers&#xff09; 1.3.存储类型说明符与存储周期的关系 2.thread_local简介 3.thread_local 应用 3.1.thread_local 与全局变量 3.2.th…

粘包拆包服务器

服务器&#xff1a; 创建个控制台应用 创建Server.cs internal class Server{TcpListener listen;public Server(IPAddress ip,int port) {listen new TcpListener(ip, port);}public void Start(){listen.Start(100);StartConnect(); }Dictionary<string,TcpClient>…

【2024德国工作】外国人在德国找工作是什么体验?

挺难的&#xff0c;德语应该是所有中国人的难点。大部分中国人进德国公司要么是做中国业务相关&#xff0c;要么是做技术领域的工程师。先讲讲人在中国怎么找德国的工作&#xff0c;顺便延申下&#xff0c;德国工作的真实体验&#xff0c;最后聊聊在今年的德国工作签证申请条件…

秀米排版的一些技巧

1.正文一般16字号 、默认字体、格式首行缩进 2.最后署名&#xff08;居中&#xff09; 文丨1234 图丨1234 排版丨1234 指导老师 | 1234 审核 |1234 信息学院研究生会宣传中心 宣 3.不必要的文字要删除 以及不必要的排版的画面 简简单单就ok 4.然后图片文字按顺序 5.最开始有个框…

Android AlarmManager 设定过去的时间会触发事件

Android AlarmManager 设定过去的时间会触发事件 在使用 AlarmManager 做每日定时任务时&#xff0c;发现如果设定的时间小于当前的系统时间&#xff0c;那么设定后会立刻收到一次定时任务回调。 我们设想的是设定的时间应该是明日的这个时间&#xff0c;但是如果打印出设定的…

【八股系列】说一下mobx和redux有什么区别?(React)

&#x1f389; 博客主页&#xff1a;【剑九 六千里-CSDN博客】 &#x1f3a8; 上一篇文章&#xff1a;【介绍React高阶组件&#xff0c;适用于什么场景&#xff1f;】 &#x1f3a0; 系列专栏&#xff1a;【面试题-八股系列】 &#x1f496; 感谢大家点赞&#x1f44d;收藏⭐评…

现代数字信号处理及其应用-常见结论

现代数字信号处理及其应用-常见结论 本文的结论均摘抄自 何子述、夏威等编著&#xff0c;《现代数字信号处理及其应用》&#xff0c;清华出版社出版。 解析信号信号预包络&#xff1b;基带信号信号复包络。BT法&#xff08;自相关谱估计法&#xff09;&#xff1a;间接法&…

双例集合(二)——双例集合的实现类之HashMap容器类

双例集合的常用实现类有HashMap和TreeMap两个&#xff0c;通过这两个类我们可以实现Map接口定义的容器&#xff0c;一般情况下使用HashMap容器类较多。 HashMap容器类是Map接口最常用的实现类&#xff0c;它的底层采用Hash算法来实现&#xff0c;这也就满足了键key不能重复的要…

Python:调用zabbix api,删除部分被监控主机

调用zabbix api&#xff0c;删除部分被监控主机。 简介代码部分配置文件config.jsonnamefile.txt 简介 当新主机上线时&#xff0c;我们可以通过自动注册功能&#xff0c;在zabbix中批量添加这些新主机。那当有主机需要下线时&#xff0c;我们又该如何在zabbix中批量删除这些主…

揭秘!速卖通、敦煌网、国际站出单背后的黑科技:自养号测评技术

在竞争激烈的跨境电商平台上&#xff0c;如亚马逊、速卖通、Lazada、Shopee、敦煌网、Temu、Shein、美客多和阿里国际等&#xff0c;稳定出单成为每位卖家共同追求的目标。为了实现这一目标&#xff0c;卖家需要从产品选择、运营策略和客户服务等多个维度进行全面考量&#xff…