计算机算法分析与设计(9)---0-1背包和完全背包问题(含C++代码)

文章目录

  • 一、0-1背包概述
    • 1.1 问题描述
    • 1.2 算法思想
  • 二、0-1背包代码
    • 2.1 题目描述
    • 2.2 代码编写
  • 三、完全背包概述
  • 四、完全背包代码
    • 4.1 题目描述
    • 4.1 代码编写
    • 4.2 代码优化


一、0-1背包概述

1.1 问题描述

 1. 0-1背包问题:给定 n n n 种物品和一背包。物品 i i i 的体积是 v i v_i vi,其价值为 w i w_i wi,背包的容量为 c c c。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

 2. 在选择装入背包的物品时,对每种物品 i i i 只有两种选择,即装入背包和不装入背包。不能将物品 i i i 装入背包多次,也不能只装入部分的物品 i i i

1.2 算法思想

 1. f [ i ] [ j ] f[i][j] f[i][j] 定义:前 i i i 个物品,背包容量 j j j 下的最优解(最大价值)。

  • 当前的状态依赖于之前的状态,可以理解为从初始状态 f [ 0 ] [ 0 ] = 0 f[0][0] = 0 f[0][0]=0 开始决策,有 n n n 件物品,则需要 n n n 次决策。每一次对第 i i i 件物品的决策,状态 f [ i ] [ j ] f[i][j] f[i][j] 不断由之前的状态更新而来。

 2. 当前背包容量不够( j < v [ i ] j < v[i] j<v[i]),没得选,因此前 i i i 个物品最优解即为前 i − 1 i−1 i1 个物品最优解。

  • 对应代码:f[i][j] = f[i - 1][j]

 3. 当前背包容量够( j > v [ i ] j > v[i] jv[i]),可以选,因此需要决策选与不选第 i i i 个物品。

  • 选:f[i][j] = f[i - 1][j - v[i]] + w[i]
  • 不选:f[i][j] = f[i - 1][j]
  • 我们的决策是如何取到最大价值,因此以上两种情况取 max() 。

二、0-1背包代码

2.1 题目描述

在这里插入图片描述

输入样例:
4 5
1 2
2 4
3 4
4 5
输出样例:
8

2.2 代码编写

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;const int MAXN = 1005;
int v[MAXN];    // 体积
int w[MAXN];    // 价值 
int f[MAXN][MAXN];  // f[i][j], j体积下前i个物品的最大价值 int main() 
{int n, m; //n表示物品的数量,m表示背包容积 cin >> n >> m;for(int i = 1; i <= n; i++) cin >> v[i] >> w[i]; //从1开始输入每个物品的体积和价值for(int i = 0; i <= m; i++) //设置在没有物品情况下,无论背包有多少体积,价值都为0f[0][i]=0;for(int j = 0; j <= n; j++) //设置在背包体积为0情况下,无论有多少物品,价值都为0f[j][0]=0;for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++){//  当前背包容量装不进第i个物品,则价值等于前i-1个物品if(j < v[i]) f[i][j] = f[i - 1][j];// 能装,需进行决策是否选择第i个物品else    f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);}           cout << f[n][m] << endl;return 0;
}

三、完全背包概述

 1. 思路同0-1背包问题。区别在于0-1背包对于每种物品只有选或不选,这也0-1的由来。而完全背包则对于每种物品可以多次选择。

 2. 因为选择物品的总体积不能超过 j j j ,所以第 i i i 件物品最多选 j / v i j / v_i j/vi(向下取整件)。

 3. f [ i ] [ j ] f[i][j] f[i][j] 定义:前 i i i 个物品,背包容量 j j j 下的最优解(最大价值)。
   f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v i ] + w i , f [ i − 1 ] [ j − 2 ∗ v i ] + 2 ∗ w i , f [ i − 1 ] [ j − k ∗ v i ] + k ∗ w i , . . . . . ) f[i] [j] = max( f[i-1][j] , f[i - 1][j - v_i]+w_i , f[i - 1][j - 2 * v_i] + 2 * w_i , f[i - 1][j - k * v_i ] + k * w_i , .....) f[i][j]=max(f[i1][j],f[i1][jvi]+wi,f[i1][j2vi]+2wi,f[i1][jkvi]+kwi,.....)

四、完全背包代码

4.1 题目描述

在这里插入图片描述

输入样例:
4 5
1 2
2 4
3 4
4 5
输出样例:
10

4.1 代码编写

#include<iostream>
using namespace std;const int N = 1010;int n, m;
int f[N][N]={0}, v[N], w[N];int main(){cin >> n >> m;for(int i = 1; i <= n; i ++ )cin >> v[i] >> w[i];for(int i = 1; i <= n; i ++ )for(int j = 1; j <= m; j ++ )for(int k = 0; k * v[i] <= j; k ++ )f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);cout << f[n][m] << endl;return 0;
}

4.2 代码优化

 1. f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v i ] + w i , f [ i − 1 ] [ j − 2 ∗ v i ] + 2 ∗ w i , f [ i − 1 ] [ j − k ∗ v i ] + k ∗ w i , . . . . . ) f[i] [j] = max( f[i-1][j] , f[i - 1][j - v_i]+w_i , f[i - 1][j - 2 * v_i] + 2 * w_i , f[i - 1][j - k * v_i ] + k * w_i , .....) f[i][j]=max(f[i1][j],f[i1][jvi]+wi,f[i1][j2vi]+2wi,f[i1][jkvi]+kwi,.....)

   f [ i ] [ j − v i ] = m a x ( f [ i − 1 ] [ j − v i ] , f [ i − 1 ] [ j − 2 ∗ v i ] + w i , f [ i − 1 ] [ j − 3 ∗ v i ] + 2 ∗ w i , . . . . . ) f[i][j - v_i] = max( f[i-1][j - v_i] , f[i-1][j - 2 * v_i] + w_i , f[i-1][j - 3 * v_i] + 2 * w_i , .....) f[i][jvi]=max(f[i1][jvi],f[i1][j2vi]+wi,f[i1][j3vi]+2wi,.....)

  由上面的两式,可得出如下递推关系:f[i][j] = max(f[i][j-v[i]] + w[i] , f[i-1][j])

 2. 去掉第三层的 k k k 循环,优化后的代码如下:

#include<iostream>
using namespace std;const int N = 1010;int n, m;
int f[N][N]={0}, v[N], w[N];int main()
{cin >> n >> m;for(int i = 1; i <= n; i ++ )cin >> v[i] >> w[i];for(int i = 1; i <= n; i ++ ){for(int j = 1; j <= m; j ++ ){if(v[i] <= j)f[i][j] =max(f[i - 1][j], f[i][j - v[i]] + w[i]);elsef[i][j] = f[i - 1][j];}}cout << f[n][m] << endl;return 0;
}

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

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

相关文章

【vue3】实现数据响应式(ref、shallowRef、trigger、reactive、shallowReactive、toRef、toRefs)

一、ref、shallowRef、trigger ref支持所有类型 可以粗略理解为 ref shallowRef triggerRef 1、通过ref获取dom元素 <p ref"_ref">这是ref获取dom元素</p>import {ref,shallowRef, triggerRef} from vueconst _ref ref()console.log(_ref.value?.i…

redis基本数据类型

一) 字符串(String) String是redis最基本的类型&#xff0c;value最大是512M&#xff0c;String类型是二进制安全的&#xff0c;可以包含任何数据&#xff0c;如jpg图片或者序列化的对象 1 使用场景 1) 缓存&#xff1a;redis作为缓存层&#xff0c;mysql做持久化层&#xff0…

AC修炼计划(AtCoder Regular Contest 166)

传送门&#xff1a;AtCoder Regular Contest 166 - AtCoder 一直修炼cf&#xff0c;觉得遇到了瓶颈了&#xff0c;所以想在atcode上寻求一些突破&#xff0c;今天本来想尝试vp AtCoder Regular Contest 166&#xff0c;但结局本不是很好&#xff0c;被卡了半天&#xff0c;止步…

力扣第538题 把二叉搜索树转换为累加树 c++

题目 538. 把二叉搜索树转换为累加树 中等 相关标签 树 深度优先搜索 二叉搜索树 二叉树 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值…

C语言 sizeof

定义 sizeof是C语言的一种单目操作符。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 使用方法 用于数据类型 sizeof(type) 数据类型必须用括号括住 用于变量 size…

ubuntu20.04 vins-fusion 运行记录

过程记录 环境&#xff1a; ubuntu20.04 opencv4.2.0(此次使用) 3.3.1(其他程序在使用) vins-fusion vision_opencv 1.下载VINS-Fusion和cv_bridge&#xff0c;并进行修改&#xff0c;方便使用opencv4.2.0和对应的cv_bridge。 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src…

C++数位动态规划算法:统计整数数目

题目 给你两个数字字符串 num1 和 num2 &#xff0c;以及两个整数 max_sum 和 min_sum 。如果一个整数 x 满足以下条件&#xff0c;我们称它是一个好整数&#xff1a; num1 < x < num2 min_sum < digit_sum(x) < max_sum. 请你返回好整数的数目。答案可能很大&…

【Linux】基本指令-入门级文件操作(二)

目录 基本指令 7 cp指令&#xff08;重要&#xff09; 8 mv指令&#xff08;重要&#xff09; 9 nano指令 10 cat指令 11 echo指令与重定向&#xff08;重要&#xff09; 12 more指令 13 less指令 基本指令 7 cp指令&#xff08;重要&#xff09; 功能&#xff1a;复…

redis如何实现缓存预热

在业务系统中&#xff0c;我们需要在程序启动的时候加载一些常用的数据到内存数据库中&#xff0c;从而减少业务数据库的压力。这就是我们常提到的缓存预热。官方一点的解释是这样的&#xff1a; 缓存预热是一种在程序启动或缓存失效之后&#xff0c;主动将热点数据加载到缓存中…

注意力屏蔽(Attention Masking)在Transformer中的作用 【gpt学习记录】

填充遮挡&#xff08;Padding Masking&#xff09;&#xff1a; 未来遮挡&#xff08;Future Masking&#xff09;&#xff1a;

09. 机器学习- 逻辑回归

文章目录 线性回归回顾逻辑回归 Hi&#xff0c;你好。我是茶桁。 上一节课&#xff0c;在结尾的时候咱们预约了这节课一开始对上一节课的内容进行一个回顾&#xff0c;并且预告了这节课内容主要是「逻辑回归」&#xff0c;那我们现在就开始吧。 线性回归回顾 在上一节课中&a…

Go语言入门心法(一)

Go语言入门心法(一) Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 一: go语言中变量认知 go语言中变量的定义: &#xff08;要想飞|先会走&#xff09;||&#xff08;翻身仗|抹遗憾 &#xff09; |&#xff08;二八定律&#xff09;(先量变)|(再质变)||&#x…

【Matlab】二维绘图函数汇总

目录 1. plot() 2. subplot() 3. fplot() 4. polarplot() 1. plot() plot() 函数是 Matlab 中最常用的绘图函数&#xff0c;用于在平面直角坐标系中绘制直线或曲线。 用法&#xff1a; plot(X,Y) plot(X,Y,LineSpec) plot(X1,Y1, ... ,Xn,Yn) 说明&#xff1a; plot(X,Y) …

Ubuntu下安装Python

Ubuntu下安装Python 预备知识一、Python安装Python 二、Anaconda安装Anaconda卸载Anaconda 三、Miniconda安装Miniconda 四、异同比较 预备知识 (1) Python是一种编程语言。 (2) Anaconda是一款包管理工具&#xff0c;用来管理Python及其他语言的安装包&#xff0c;预装了很多…

【考研408真题】2022年408数据结构41题---判断当前顺序存储结构树是否是二叉搜索树

文章目录 思路408考研各数据结构C/C代码&#xff08;Continually updating&#xff09; 思路 很明显&#xff0c;这是一个顺序存储结构的树的构成方法。其中树的根节点位置从索引0开始&#xff0c;对于该结构&#xff0c;存在有&#xff1a;如果当前根节点的下标为n&#xff0c…

凉鞋的 Unity 笔记 108. 第二个通识:增删改查

在这一篇&#xff0c;我们来学习此教程的第二个通识&#xff0c;即&#xff1a;增删改查。 增删改查我们不只是一次接触到了。 在最先接触的场景层次窗口中&#xff0c;我们是对 GameObject 进行增删改查。 在 Project 文件窗口中&#xff0c;我们是对文件&文件夹进行增删…

Jetpack:007-Kotlin中的Button

文章目录 1. 概念介绍2. 使用方法2.1 Button2.2 IconButton2.3 ElevatedButton2.4 OutlinedButton2.5 TextButton2.6 FloatingActionButton 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack中输入框相关的内容&#xff0c;本章回中将要介绍 Button。闲话休提&#xff0…

使用【Blob、Base64】两种方式显示【文本、图片、视频】 使用 video 组件播放视频

Blob 显示 Blob 对象的类型是由 MIME 类型&#xff08;Multipurpose Internet Mail Extensions&#xff09;来确定的。MIME 类型是一种标准&#xff0c;用于表示文档、图像、音频、视频等多媒体文件的类型。以下是一些常见的 Blob 对象类型&#xff1a; text/plain&#xff1…

drone如何发布docker服务

上篇主要实现了drone在物理机上进行发布程序&#xff0c;这次介绍drone如何发布docker类型的服务。 一 drone.yml文件配置 前提&#xff1a;需要提前在drone里添加文件里面所引用的密钥 kind: pipeline # 定义对象类型&#xff0c;还有secret和signature两种类型 type: dock…

SaaS人力资源管理系统的Bug

SaaS人力资源管理系统的Bug Bug1【18】 这里我是直接把代码复制过来的&#xff0c;然后就有一个空白 这是因为它的代码有问题&#xff0c;原本的代码如下所示 <el-table-column fixed type"index" label"序号" width"50"></el-table…