01背包和完全背包

01背包问题和完全背包问题 01背包 01背包字面意思来看0就是不拿,1就是拿,且每次只能拿一个物品放入背包。 开二维数组的状态方程: 此情景为往固定容量的背包里装物品,使包内物品为最大价值 实际上就是在每个物品的基础上,遍历所有可能的背包空间,如果放得下去就比较放与不放对价值的影响 一维数组的状态方程: ... 阅读详情

01背包:

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

从这个题目中可以看出,01背包的特点就是:每种物品仅有一件,可以选择放或不放。

其状态转移方程是:

dp[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

对于这方方程其实并不难理解,方程之中,现在需要放置的是第i件物品,这件物品的体积是c[i],价值是w[i],因此f[i-1][v]代表的就是不将这件物品放入背包,而f[i-1][v-c[i]]+w[i]则是代表将第i件放入背包之后的总价值,比较两者的价值,得出最大的价值存入现在的背包之中。

理解了这个方程后,将方程代入实际题目的应用之中,可得

for(i = 1; i<=n; i++)  
{  
    for(j = v; j>=c[i]; j--)//在这里,背包放入物品后,容量不断的减少,直到再也放不进了  
    {  
        f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]);  
    }  
} 

以下直接给出优化后的代码:
//求解将哪些物品装入背包可使这些物品的重量总和不超过背包承重量t,且价值总和最大。

#include <stdio.h>
#include <string.h>

int f[1010],w[1010],v[1010];//f记录不同承重量背包的总价值,w记录不同物品的重量,v记录不同物品的价值

int max(int x,int y){//返回x,y的最大值
    if(x>y) return x;
    return y;
}

int main(){
    int t,m,i,j;
    memset(f,0,sizeof(f));  //总价值初始化为0
    scanf("%d %d",&t,&m);  //输入背包承重量t、物品的数目m
    for(i=1;i<=m;i++)
        scanf("%d %d",&w[i],&v[i]);  //输入m组物品的重量w[i]和价值v[i]
    for(i=1;i<=m;i++){  //尝试放置每一个物品
        for(j=t;j>=w[i];j--){//倒叙是为了保证每个物品都使用一次
            f[j]=max(f[j-w[i]]+v[i],f[j]);
            //在放入第i个物品前后,检验不同j承重量背包的总价值,如果放入第i个物品后比放入前的价值提高了,则修改j承重量背包的价值,否则不变
        }
    }
    printf("%d",f[t]);  //输出承重量为t的背包的总价值
    printf("\n");
    getch();
    return 0;
}

完全背包:

 完全背包:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。  
 根据第i种物品放多少件进行决策,所以状态转移方程为
这里写图片描述

     其中F[i-1][j-K*C[i]]+K*W[i]表示前i-1种物品中选取若干件物品放入剩余空间为j-K*C[i]的背包中所能得到的最大价值加上k件第i种物品;

     设物品种数为N,背包容量为V,第i种物品体积为C[i],第i种物品价值为W[i]。

     与01背包相同,完全背包也需要求出NV个状态F[i][j]。但是完全背包求F[i][j]时需要对k分别取0,…,j/C[i]求最大F[i][j]值。

很明显,这样一般情况下会超时,需要转化成时间复杂度比较低的在进行求解

  经过思考可以想到完全背包可以转化为01背包:

   因为同种物品可以多次选取,那么第i种物品最多可以选取V/C[i]件价值不变的物品,然后就转化为01背包问题。如果把第i种物品拆成体积为C[i]×2k价值W[i]×2k的物品,其中满足C[i]×2k≤V。即设F[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。那么对于第i种物品的出现,我们对第i种物品放不放入背包进行决策。如果不放那么F[i][j]=F[i-1][j];如果确定放,背包中应该出现至少一件第i种物品,所以F[i][j]种至少应该出现一件第i种物品,即F[i][j]=F[i][j-C[i]]+W[i]。为什么会是F[i][j-C[i]]+W[i]?因为F[i][j-C[i]]里面可能有第i种物品,也可能没有第i种物品。我们要确保F[i][j]至少有一件第i件物品,所以要预留C[i]的空间来存放一件第i种物品。

  状态方程为:这里写图片描述

#include<cstdio>
#include<algorithm>
using namespace std;
int w[300],c[300],f[300010];
int V,n;
int main()
{
    scanf("%d%d",&V,&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d%d",&w[i],&c[i]);
    }
    for(int i=1; i<=n; i++)
        for(int j=w[i]; j<=V; j++)//注意此处,与0-1背包不同,这里为顺序,0-1背包为逆序
            f[j]=max(f[j],f[j-w[i]]+c[i]);
    printf("max=%d\n",f[V]);
    return 0;
}

 0-1背包和完全背包的不同:

  从二维数组上区别0-1背包和完全背包也就是状态转移方程就差别在放第i中物品时,完全背包在选择放这个物品时,最优解是F[i][j-c[i]]+w[i]即画表格中同行的那一个,而0-1背包比较的是F[i-1][j-c[i]]+w[i],上一行的那一个。

  从一维数组上区别0-1背包和完全背包差别就在循环顺序上,0-1背包必须逆序,因为这样保证了不会重复选择已经选择的物品,而完全背包是顺序,顺序会覆盖以前的状态,所以存在选择多次的情况,也符合完全背包的题意。状态转移方程都为F[i] = max(F[i],dp[F-c[i]]+v[i])。

算法之01背包问题和完全背包问题 01背包问题,多重背包问题,完全背包问题的详细描述(适合有基础的人看): 初始化合法状态解释:背包问题的dp数组的初始化其实就是合法状态的情况,就是在没有任何物品可以放入背包是的合法状态。假如说题目要求背包恰好装满的话,那么此时只有容量为0时的背包可以在什么也不装的状态下“恰好装满”,此时背包价值为0,其他容量的背包都没有合法的解,属于未定义的状态,所以我们就要定义非法值,通常为负无穷大,正无穷大,或者足够大或小的值,从而保证当前的合法解,一定是从之前的合法状态推导而来的。 正逆序解释:对于二维数组背包来说 阅读详情

相关推荐

华为服务器RAID配置避坑指南:如何通过iBMC快速识别阵列卡型号并完成初始化

本文详细解析华为服务器RAID配置全流程,重点介绍通过iBMC快速识别阵列卡型号、硬盘健康诊断及RAID级别选择的场景化策略。提供从iBMC登录到缓存策略调优的实战技巧,帮助工程师避免常见配置陷阱,提升服务器存储系统性能和稳定性。

weixin_28475533的博客 490

AcWing 3.完全背包问题

有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。 第 i 种物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。 输出格式 输出一个整数,表...

Allen的博客 622

Centos7网络配置(设置固定ip)

刚安装完系统,有的人尤其没有勾选自动网络配置的情况下,是访问不了外网的,本机也连不通虚拟机。或者现在有的是动态ip,几次之后启动ip地址就变了,会导致其他软件或程序之前连接配置要重新更改,很麻烦,下面讲解一下如何配置网络,如何设置成固定ip。

个人笔记git:https://gitee.com/tlangp/note.git 8053

01背包和完全背包区别

状态与上一层有关(放完i-1个物品之后),如果是正序,先更新第一个背包,到第二个背包的时候,得根据上一层的第一个背包和上一层的自身退出来,但是上一层的第1个背包已经被更新了,如果再拿更新过的来推导出,就会使用同一个物品。过程:先对最后一个背包,从第一个物品开始比较,放入第一个,对于更大的物品,就会覆盖之前的物品,最终导致有且仅有一个物品放入了背包。先背包后物品,那么只会在每一个背包里放0-i个物品的最大值。01背包和完全背包区别在于,对于物品拿一次和多次区别!

qq_63819197的博客 1130

[TI板]MSPM0G3507——keil环境配置+烧录配置+vscode配置+空工程迁移+点灯+芯片解锁教程

本文介绍了MSPM0G3507开发环境的配置与烧录方法。主要内容包括:1)下载安装芯片支持包和SDK开发工具;2)通过串口或DAPLink两种方式实现程序烧录,详细说明了UniFlash软件的使用步骤和常见问题解决方法;3)简要提及工程迁移和LED点灯等基础操作。文章提供了完整的开发环境搭建指南,涵盖从软件安装到实际烧录的全过程,并附有相关工具下载链接和操作截图,帮助开发者快速上手MSPM0G3507开发。

qq_23220445的博客 1万+

Windows下Python多版本共存与切换的终极指南(含环境变量详解)

本文详细解析了在Windows系统下实现Python多版本共存与切换的完整方案。通过深入讲解环境变量Path的底层机制,提供了从安装策略、精细化Path管理到创建快速切换脚本的实战指南,并介绍了py启动器和虚拟环境等高级技巧,帮助开发者彻底解决版本冲突问题,提升开发效率。

v6b7n8m9q0的博客 536

完全背包与01背包

这个转移的状态V[i][j]的含义即在考虑第0--i个物品时,容量为j的背包所能承载的最大价值。首先,当背包容量j

qq_42987967的博客 892

Allegro Design Entry CIS 与 OrCAD Capture CIS:PCB设计工具链中的双雄对决

本文深入对比了Cadence旗下两大原理图设计工具Allegro Design Entry CIS与OrCAD Capture CIS。Allegro Design Entry CIS源自Concept HDL,定位高端,强调自顶向下的层次化设计和与Allegro PCB Editor的无缝约束管理,适合大型复杂系统及团队协作。OrCAD Capture CIS则以其出色的易用性、广泛的兼容性和强大的CIS数据库功能著称,是中小型项目及跨工具链协作的通用选择。文章从历史渊源、核心功能、适用场景等多维度剖析,

bush的博客 486

01背包与完全背包详解

背包问题 文章目录背包问题dp定义关于背包的两个关键点01背包二维先遍历物品先遍历背包一维(倒着遍历防止被重复放入,详解看图)完全背包什么是完全背包问题[279. 完全平方数](https://leetcode-cn.com/problems/perfect-squares/)先遍历物品后遍历背包先遍历背包后遍历物体状态压缩过程要考虑插入顺序的完全背包问题 只需要知道0-1背包和完全背包问题就完全足够了 0-1背包有以下的特点 有限个物体(有重量和价值),每个物体只有一个 每个物体你都可以任选,可选也可

ahelloyou的博客 4418

基于RK3588的高效音视频对讲系统设计与实现

本文详细介绍了基于RK3588芯片的高效音视频对讲系统设计与实现。文章深入剖析了RK3588在8K编解码、高性能音频DSP及丰富接口方面的优势,并提供了从开发环境搭建、分层软件架构设计,到视频采集编码、音频回声消除及低延迟网络传输的完整实战指南,旨在帮助开发者充分利用该芯片硬件能力,构建稳定、低延迟的实时通信系统。

dapp9builder的博客 254

别再只会插卡了!用示波器实测SIM卡上电时序与通信波形(附故障排查)

本文深入解析了SIM卡通信的电气信号与时序规则,通过示波器实测波形揭示SIM卡上电时序与通信协议的关键细节。从VCC、CLK、RST、DATA四路信号的协同工作,到ATR(Answer to Reset)的解析,再到常见故障的波形诊断与排查方法,为硬件工程师提供了实用的调试指南。文章还分享了高级调试技巧与现代化工具链搭建建议,帮助提升物联网设备SIM卡通信的可靠性与效率。

weixin_42567279的博客 325

背包问题(01,完全)

1:背包问题的难点不是在于这个状态转移方程,难得是初始化和确定遍历顺利这两步。2:背包问题的滚动数组的方式是由二维数组压缩而来的,碰到题目可以先尝试把二维数组的代码写出来。3:至此,01背包的题目算是刷的差不多了,我感觉能用01背包解决的题目都有一个共同点:就是要分堆,题目的不同就是分堆规则的不同,和我们要求的东西的不同而有来不及休息了,接下来要登场的是。

m0_73966521的博客 1494

YOLOv11知识蒸馏实战:让小模型拥有大模型90%精度,速度提升3倍的终极教程

在self.alpha = alpha # 蒸馏损失权重self.temperature = temperature # 温度系数,控制分布平滑度# 输出分布蒸馏(KL散度损失)# 中间特征蒸馏(MSE损失,对齐中间层特征)# 总蒸馏损失知识蒸馏是YOLOv11在“小模型高性能部署”场景的“破局之法”——它让小模型能“站在大模型的肩膀上”,兼具速度与精度。从损失函数定义到多阶段训练,再到实战落地,本教程已为你铺就了一条清晰的路径。

m0_64661770的博客 800

动态规划——01背包和完全背包

有一个背包能容纳的体积是v,现在有n个物品,第i个物品的体积为vi,价值为wi。 (1)求这个背包至多能装多大价值的物品? (2) 若背包恰好装满,求至多能装多大价值的物品? 输入描述: 第一行两个整数n和V,表示物品个数和背包体积接下来n行,每行两个数u;和wi表示第i个物品的体积和价值

申俏雅的博客 1382

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C++ 01背包和完全背包

用C++ 代码,实现01背包和完全背包 #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<climits> using namespace std; int N, V; in...

ding_programmer的博客 2027

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

01背包和完全背包(java)

所有的w和v数组下标都按从1开始了,方便描述问题,需要改就在用到w和v的地方下标-1就行。 01背包 给定n个物品,体重分别为w1,w2,w3…,价值分别为v1,v2,v3…,且每个物品只有一件,现在有一个容量为C的背包,求最多能装价值多大的东西。 通过枚举物品种类和背包的容量来解决该问题,现在假设有4件物品,对应的体积和价值如下表所示,背包的容量为10。 i 1 2 3 4 w(体积) 10 3 4 5 v(价值) 3 4 6 7 dp状态表如下所示,dp[i][j]表示当前只有i

weixin_43805402的博客 1280

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【背包问题】之01背包和完全背包

背包问题 01 背包 完全背包 动态规划与递归

weixin_54383080的博客 732

01背包问题(不装满和装满)和完全背包问题

给定一个容量为。

2303_80261633的博客 1506
上一篇: 多重背包模板
下一篇: 最大连续子序列
Puppet__
博客等级 码龄9年 319粉丝 328原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值