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

news2024/9/30 17:28:55

目录

 介绍:

一、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;
    else
        cout<<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) //该体积为该物体体积的倍数或者该体积减去物体体积不为0
                    dp2[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));//清空为0
		f[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.coloradmin.cn/o/1472668.html

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

相关文章

Mybatis2

Mybatis2 本章目标&#xff1a; myBatis类型别名处理 myBatis参数处理 myBatis结果集类型 myBatis结果集列名和属性名称对应方式处理 附录 本章内容 一、类型别名&#xff08;typeAliases&#xff09;处理 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置…

使用EFCore连接SQLite

简介 在使用EFCore连接SQLite之前我们先来了解一下SQLite SQLite是一个轻量级、自包含、无服务器、零配置的事务性SQL数据库引擎&#xff0c;它支持SQL92标准的大多数查询语言并兼容ACID事务。具体如下&#xff1a; 轻量级&#xff1a;SQLite非常轻巧&#xff0c;它的库体积…

[算法沉淀记录] 排序算法 —— 堆排序

排序算法 —— 堆排序 算法基础介绍 堆排序&#xff08;Heap Sort&#xff09;是一种基于比较的排序算法&#xff0c;它利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树&#xff0c;其中每个节点的值都必须大于或等于&#xff08;最大堆&#xff09;或小于或等于&am…

Huggingface学习笔记

课程地址&#xff1a;【HuggingFace简明教程,BERT中文模型实战示例.NLP预训练模型,Transformers类库,datasets类库快速入门.】 什么是huggingface&#xff1f; huggingface是一个开源社区&#xff0c;提供了先进的NLP模型、数据集以及工具。 主要模型&#xff1a; 安装环境&…

Rust升级慢,使用国内镜像进行加速

背景 rustup 是 Rust 官方的跨平台 Rust 安装工具&#xff0c;国内用户使用rustup update的时候&#xff0c;网速非常慢&#xff0c;可以使用国内的阿里云镜像源来进行加速 0x01 配置方法 1. Linux与Mac OS用户配置环境变量 修改~/.bash_profile文件添加如下内容&#xff1…

Docker基础篇(六) dockerfile体系结构语法

FROM&#xff1a;基础镜像&#xff0c;当前新镜像是基于哪个镜像的 MAINTAINER &#xff1a;镜像维护者的姓名和邮箱地址 RUN&#xff1a;容器构建时需要运行的命令 EXPOSE &#xff1a;当前容器对外暴露出的端口号 WORKDIR&#xff1a;指定在创建容器后&#xff0c;终端默认登…

lv21 QT入门与基础控件 1

1 QT简介 QT是挪威Trolltech开发的多平台C图形用户界面应用程序框架 典型应用 2 工程搭建 2.1 新建ui工程 不要写中文路径 2.1 不勾选UI&#xff08;主讲&#xff09; 3 QT信号与槽机制 语法&#xff1a;Connect&#xff08;A, SIGNLA(aaa()), B, SLOT(bbb())&#xff09;…

算法--贪心

这里写目录标题 区间问题区间选点引入算法思想例题代码 最大不相交区间的数量算法思想例题代码 区间分组算法思想例题代码 一级目录二级目录二级目录二级目录 区间问题 区间选点 引入 区间问题会给定几个区间&#xff0c;之后要求我们在数轴上选取尽量少的点&#xff0c;使得…

电脑休眠之后唤不醒

现象&#xff1a;午休时间电脑休眠了&#xff0c;醒来之后发现在密码输入界面&#xff0c;但鼠标键盘没反应。按重启键或电源机重新开机&#xff0c;结果开不了机。 原因&#xff1a;1、内存条脏了&#xff0c;导致内存条读取失败 2、休眠的时候硬盘休眠了&#xff0c;导致按…

欢迎免费申报讯方技术HarmonyOS人才训练营!

在今年1月备受瞩目的鸿蒙生态千帆启航仪式上&#xff0c;华为宣布&#xff1a;HarmonyOS NEXT星河预览版正式面向开发者开放申请&#xff0c;意味着鸿蒙将建立更广泛的生态系统&#xff0c;迎来更多的应用和软硬件产品&#xff0c;加速自我技术迭代&#xff0c;同时推动华为全场…

变革中的容器技术

容器化技术的优点 容器化是一种将应用程序和其所需的依赖项&#xff0c;封装在一个可在任何基础架构上一致运行的轻量级可执行文件&#xff08;即容器&#xff09;的技术。容器化技术可以大大简化应用程序的部署、管理和维护&#xff0c;提高运维效率和可靠性。 容器化技术有…

LeetCode_Java_动态规划(2)(题目+思路+代码)

131.分割回文串 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xff1a; 输入&#xff1a;s "aab" 输出&#xff1a;[["a&qu…

工具篇-- 定时任务xxl-job的集群部署

文章目录 前言一、xxl-job-admin 集群部署&#xff1a;1.1 部署步骤&#xff1a;1.2 部署求和建议&#xff1a;1.3 集群部署模拟&#xff08;单机&#xff09;&#xff1a; 二、xxl-job 执行器 集群部署&#xff1a;2.1 集群部署要求&#xff1a;2.2 集群部署模拟&#xff1a; …

pthread_exit和pehread_join函数

pthread_exit&#xff1a; 在线程中禁止调用exit函数&#xff0c;否则会导致整个进程退出&#xff0c;取而代之的是调用pthread_exit函数&#xff0c;这个函数只会使一个线程退出&#xff0c;如果主线程使用pthread_exit函数也不会使整个进程退出&#xff0c;不会影响其他线程…

【基础知识】MPP架构和hadoop架构比对

架构比对 简单一句描述。 mpp架构&#xff0c;就是找一群和自己能力差不多的任一起做事&#xff0c;每个人做的事情是一致的。 hadoop架构&#xff0c;就是找一群能力差一些的人&#xff0c;但只需要他们每个人只做一部分工作。 举例说明 一个特色小饭店如何成为连锁餐饮巨…

【国密算法】深入理解国密算法:原理、实践及注意事项

目录 引言 1. 国密算法概述 2. 国密算法的实践应用 2.1 对称加密&#xff08;SM1算法&#xff09; 2.2 非对称加密&#xff08;SM2算法&#xff09; 2.3 哈希算法&#xff08;SM3算法&#xff09; 3. 国密算法的注意事项 结论 引言 国密算法&#xff0c;即中国密码算法…

AI数字人SadTalker实战

1.概述 AI数字人在营销和品牌推广中扮演着至关重要的角色&#xff0c;许多企业和个人正积极利用数字技术来打造属于自己的财富。有没有一种简单而免费的方式来创建自己的数字人呢&#xff1f;本篇博客笔者将为大家介绍如何搭建属于自己的AI数字人。 2.内容 2.1 什么是SadTalker…

内存卡无法读取?这里有救!

一、遭遇内存卡无法读取的困境 在日常生活和工作中&#xff0c;我们越来越依赖电子设备来存储和传输数据。然而&#xff0c;当遇到内存卡无法读取的问题时&#xff0c;很多人会感到困惑和焦虑。无论是重要的工作文件、珍贵的家庭照片&#xff0c;还是其他个人数据&#xff0c;…

基于springboot+vue的音乐网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

C++力扣题目 42--接雨水 84--柱状图中最大的矩形

42. 接雨水 力扣题目链接(opens new window) 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1]输出&#xff1a;6解释&#xff…