背包问题(介绍+例题+代码+注解)

目录

 介绍:

一、01背包

题目描述

输入描述:

输出描述:

代码:

 二、完全背包

题目描述

输入描述:

输出描述:

代码: 

三、多重背包

题目描述

输入描述:

输出描述:

代码: 

四、背包问题 

题目描述

输入描述:

输出描述:

代码: 

 五、变1

代码: 

 六、变2

代码: 

 七、变3

代码:


 介绍:

背包问题是一个经典的组合优化问题,它的目标是在给定的一组物品中选择一些物品放入背包中,使得这些物品的总价值最大化,同时限制背包的容量。

背包问题有多种变体,其中最常见的是0-1背包问题。在0-1背包问题中,每个物品要么完整地放入背包中,要么不放入,不存在放入一部分的情况。每个物品都有对应的价值和重量,背包有一个固定的容量限制。问题在于选择哪些物品放入背包中,使得总价值最大化,同时不超过背包的容量。

解决背包问题的方法包括动态规划、贪心法和回溯法。动态规划是最常用的解决方法,其基本思想是将问题划分为子问题,并使用一个二维数组来保存子问题的最优解。贪心法则是每次选择当前最有利的物品放入背包,但不一定能得到最优解。回溯法则是穷举所有可能的解,并逐步剪枝,但在处理大规模问题时效率较低。

背包问题具有广泛的应用,例如资源分配、排课问题、投资组合优化等。

一、01背包

题目描述

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

现在有n个物品,第i个物品的体积为v ,价值为w。

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

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

输入描述:

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

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

1≤n,V,vi,wi≤10001 \le n,V,v_i,w_i \le 10001≤n,V,vi​,wi​≤1000

输出描述:

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

代码:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{int n, v;cin >> n >> v;int a[1005],b[1005];int f[1005][1005];//表示第i个物品装满j体积memset(f, -0x3f, sizeof(f));for (int i = 1; i <= n; i++)cin >> a[i] >> b[i];int ans = 0;f[0][0]=0;//0个物体可以装满0体积for(int i=1;i<=n;i++)for (int j = 0; j <= v; j++){if(a[i]<=j)//体积大于该物体体积,才可以装物品f[i][j] = max(f[i - 1][j], f[i - 1][j - a[i]] + b[i]);else//不装该物体f[i][j]=f[i-1][j];if (ans < f[i][j])//求最大价值ans = f[i][j];}cout << ans << endl;if(f[n][v]>0)cout << f[n][v] << endl;elsecout<<0;
}

 二、完全背包

题目描述

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

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

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

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

输入描述:

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

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

1≤n,V≤10001 \le n, V \le 10001≤n,V≤1000

输出描述:

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

代码: 

#include<iostream>
#include<cstring>
using namespace std;
int main()
{long long n, V;cin >> n >> V;long long dp1[1010], dp2[1010];memset(dp1, 0, sizeof(dp1)), memset(dp2, 0, sizeof(dp2));for (int i = 1; i <= n; i++){long long v, w;cin >> v >> w;for (int j = 0; j <= V; j++){if (j >= v){dp1[j] = max(dp1[j], dp1[j - v] + w);if (j % v == 0 || dp2[j-v] != 0) //该体积为该物体体积的倍数或者该体积减去物体体积不为0dp2[j] = max(dp2[j], dp2[j - v] + w);//塞这个物品,原先该体积的价值和减去该体积的价值加塞下该物品的价值谁大}}}cout << dp1[V] << endl;cout << dp2[V] << endl;
}

三、多重背包

题目描述

有 n 种物品,第 i 种物品有 x​ 个,每一个物品重量为 w ,价值为 v,现有一个承重能力为 T 的背包,在不超过承重能力的情况下,背包种最多能装多少价值的物品。

输入描述:

第一行输入两个整数 n,T(1≤n,T≤100)n,T(1\le n,T \le 100)n,T(1≤n,T≤100) ,代表物品种数和背包承重能力。

接下来 nnn 行,每行三个整数 xi,wi,vi(1≤xi,wi≤20,1≤vi≤200)x_i,w_i,v_i(1\le x_i,w_i\le 20,1\le v_i \le 200)xi​,wi​,vi​(1≤xi​,wi​≤20,1≤vi​≤200) 描述一个物品,分别代表物品的个数、物品的重量、物品的价值。

输出描述:

输出一行一个整数,表示在不超过承重能力的情况下,背包物品的最大价值。

代码: 

#include<iostream>
using namespace std;
int main()
{int n, t;cin >> n >> t;int f[105][105];//表示第i个物品装j体积for (int i = 1; i <= n; i++){int x, w, v;cin >> x >> w >> v;for (int j = 0; j <= t; j++){for (int k = 0; k <= x; k++)//表示放k个该物品if(j>=k*w)//要该体积大于k个物品体积才能放那么多个物品f[i][j] = max(f[i][j], f[i - 1][j - k * w] + k*v);}}cout << f[n][t];
}

四、背包问题 

题目描述

牛妹家里有n个物品,第i个物品体积为v​,价值为w​。牛妹有一个容积无穷大的背包,背包可以装任意多的物品,没有限制。
牛妹要去深山中度假,为了在旁人眼中显得自己准备得很充分,牛妹想在背包中装入总体积不小于V的一些物品。如果装入的物品过于贵重,路上如果遇到强盗、劫匪、山贼等就很亏。所以牛妹想知道总体积不小于V的前提下,物品的总价值最小是多少。

输入描述:

第一行两个整数n,V\mathit n,Vn,V,表示物品的数量和总体积需求。

接下来n\mathit nn行,每行两个整数vi,wiv_i,w_ivi​,wi​,表示第i\mathit ii种物品的体积和价值。保证所有物品总体积不小于V\mathit VV。

1≤n≤200,1≤V≤106,1≤vi≤106,1≤wi≤2001 \leq n \leq 200, 1 \leq V \leq 10^6, 1 \leq v_i \leq 10^6, 1 \leq w_i \leq 2001≤n≤200,1≤V≤106,1≤vi​≤106,1≤wi​≤200。保证所有物品总体积不小于V\mathit VV。

输出描述:

输出一个整数,表示答案。

代码: 

#include<iostream>
using namespace std;
int v[1000100], w[1000100];
int f[1000100];//j价值可以装的最大体积
int main()
{int n,V;long long sum = 0;cin >> n >> V;for (int i = 1; i <= n; i++){cin >> v[i] >> w[i];sum += w[i];//总价值}for (int i = 1; i <= n; i++){for (int j = sum; j >= w[i]; j--)f[j] = max(f[j], f[j - w[i]] + v[i]);}for (int i = 1; i <= sum; i++)if (f[i] >= V)//找到大于等于V体积的最小价值{cout << i << endl;break;}
}

 五、变1

代码: 

#include<iostream>
using namespace std;
int main()
{int n, m;cin >> n >> m;int v[30], p[30];for (int i = 1; i <= m; i++){cin >> v[i] >> p[i];}long long dp[30010] = { 0 };//当存体积为j时的,价值最大值for(int i=1;i<=m;i++)for (int j = n; j >= v[i]; j--)//当存到第i个时,花费为j时价值的最大值{dp[j] = max(dp[j], dp[j - v[i]] + p[i] * v[i]);//不选取i则继承存到第i-1个时的最大值,选取i则最大值更新为减去第i个花费时的最大值dp加上第i个的价值,即dp[j - v[i]] + p[i] * v[i]}cout << dp[n] << endl;
}

 六、变2

代码: 

#include<iostream>
#include<cstring>
using namespace std;
int main()
{int t;cin >> t;while (t--){int n, s;cin >> n >> s;long long  f[500000], q[500000];//f记录j体积的最高战力,q记录j体积的精灵数量memset(f, 0, sizeof(f)), memset(q, 0, sizeof(q));for (int i = 1; i <= n; i++){int w, v;cin >> w >> v;for (int j = s; j >= w; j--){if (f[j] < f[j - w] + v)//装该精灵战力更高,则更新{f[j] = f[j - w] + v;q[j] = q[j-w]+1;}}}cout << f[s] << " "<<q[s]<<endl;}
}

 七、变3

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[105], f[25005];//f[i]表示价值i是否可以表示
int main()
{int t;cin>>t;while (t--){int n;cin >> n;int ans = n;for (int i = 1; i <= n; i++)cin >> a[i];sort(a + 1, a + n + 1);//从小到大排序memset(f, 0, sizeof(f));//清空为0f[0] = 1;for (int i = 1; i <= n; i++){if (f[a[i]] == 1)//a[i]该数值可以被之前表示,则ans--,这个票不需要用到{ans--;continue;}for (int k = a[i]; k <= a[n]; k++)//a[i]该数值不可以被表示,则从该数值到最大值,将加上a[i]后可以表示的数赋值为1{f[k] = f[k] || f[k - a[i]];}}cout << ans << endl;}
}

 

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

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

相关文章

27.HarmonyOS App(JAVA)可复用列表项的ListContainer

可复用列表项的ListContainer 简短的列表可以通过定向布局实现,但是如果列表项非常多,则使用定向布局就不再合适。如需要创建50个列表项的列表,那么用定向布局实现至少需要创建50个以上的组件了。然而,限于设备屏幕大小的限制,绝大多数组件不会显示在屏幕上,却会占据大量的内存…

基础光学系列:(二)光学元件在机器视觉中的关键作用

光学元件&#xff0c;包括透镜、反射镜和棱镜&#xff0c;在机器视觉领域扮演着至关重要的角色。它们不仅是实现高精度图像捕获的基础&#xff0c;也是提升机器视觉系统性能的关键。通过深入了解这些光学元件的功能和应用&#xff0c;我们能够更好地掌握机器视觉技术的精髓。 …

算法-计算机基础知识

1&#xff0c;坐标系与数学不同&#xff0c;x轴向下&#xff0c;y轴向右 2.案例&#xff1a;螺旋矩阵 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class Solution {public List<Integer> spiralOrder(int[][] matrix) { List<Integer&…

Linux使用Docker部署Nacos容器并结合内网穿透实现公网访问本地服务

文章目录 推荐1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff…

互联设备-中继器-路由器等

网卡的主要作用 1 在发送方 把从计算机系统要发送的数据转换成能在网线上传输的bit 流 。 2 在接收方 把从网线上接收来的 bit 流重组成计算机系统可以 处理的数据 。 3 判断数据是否是发给自己的 4 发送和控制计算机系统和网线数据流 计算机的分类 1、台式机 2、小型机和服…

【网站项目】437物流管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

第六十八天 APP攻防-XposedFridaHook证书校验反代理代理转发

第68天 APP攻防-Xposed&Frida&Hook&证书校验&反代理&代理转发 知识点&#xff1a; 1、APP防代理绕过-应用&转发 2、APP证书校验类型-单向&双向 3、APP证书校验绕过-Frida&XP框架等 章节点&#xff1a; 1、信息收集-应用&资产提取&权…

【可实战】被测系统业务架构、系统架构、技术架构、数据流、业务逻辑分析

一、为什么要学习 更深的理解业务逻辑&#xff08;公司是做什么的&#xff1f;它最重要的商务决策是什么&#xff1f;它里面的数据流是怎么做的&#xff1f;有哪些业务场景&#xff1f;考验你对这家公司、对所负责业务的熟悉程度。公司背后服务器用什么软件搭建的&#xff1f;…

【Golang切片】

切片 切片的引入内存分析切片的定义切片的遍历切片注意事项 切片的引入 【1】切片&#xff08;slice&#xff09;是golang中一种特有的数据类型 【2】数组有特定的用处&#xff0c;但是却有一些呆板&#xff08;数组长度固定不可变&#xff09;&#xff0c;所以在Go语言的代码…

AIGC专栏9——Scalable Diffusion Models with Transformers (DiT)结构解析

AIGC专栏9——Scalable Diffusion Models with Transformers &#xff08;DiT&#xff09;结构解析 学习前言源码下载地址网络构建一、什么是Diffusion Transformer (DiT)二、DiT的组成三、生成流程1、采样流程a、生成初始噪声b、对噪声进行N次采样c、单次采样解析I、预测噪声I…

Unity发布webgl获取浏览器的URL

Unity发布webgl获取浏览器的URL Unity发布webgl之后获取浏览器的url 在unity中创建文件夹Plugins&#xff0c;然后添加添加文件UnityGetBrowserURL.jslib var GetUrlFunc {//获取地址栏的URLStringReturnValueFunction: function () {var returnStr window.top.location.hre…

Darkhole 2

kali:192.168.223.128 靶机:192.168.223.152 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.152 开启了22 80 端口 web 进入登录界面发现没有注册按钮了 扫一下目录 gobuster dir -u http://192.168.223.152 -x html,txt,php,bak,zip,git --wor…