首页 > 其他分享 >背包

背包

时间:2023-08-12 22:47:05浏览次数:36  
标签:件物品 容量 max leq 背包 物品

01背包

给定 \(n\) 件物品,每个物品有重量 \(w_{i}\) 和价值 \(c_{i}\),一个物品只有一件,求容量不超过 \(m\) 的背包最多可以装多少价值物品

定义 \(f_{i,j}\) 表示前 \(i\) 件物品在容量不超过 \(j\) 的背包下可以获得的最大价值则有 \(f_{i,j}=\max\{f_{i-1,j},f_{i-1,j-w_{i}}+c_i\}\)

for(int i=1; i<=n; ++i)
	for(int j=w[i]; j<=m; ++j)
		f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i]);

考虑优化空间复杂度,我们会发现对于一个 \(f_{i,j}\),与其有关的状态 \(f_{x,y}\) 满足 \(x=i-1,y\leq j\),所以不妨把表示物品件数的一维去掉然后倒序计算,因为结果只与容量小的那一部分有关。定义 \(f_j\) 表示在容量不超过 \(j\) 的背包中可以获得的最大价值,有\(f_j=\max\{f_j,f_{j-w_i}+c_i\}\)

for(int i=1; i<=n; ++i)
	for(int j=m; j>=w[i]; --j)
		f[j]=max(f[j],f[j-w[i]]+c[i]);

完全背包

给定 \(n\) 件物品,每个物品有重量 \(w_{i}\) 和价值 \(c_{i}\),一个物品有无限件,求容量不超过 \(m\) 的背包最多可以装多少价值物品

定义 \(f_{i,j}\) 表示前 \(i\) 件物品在容量不超过 \(j\) 的背包下可以获得的最大价值,有

\[f_{i,j}=\max\{f_{i-1,j},f_{i-1,j-k*w_i}+k*c_i\}, 0\leq k*c_i\leq j \]

其实就相当于把无限件转化为有限件做 01 背包

考虑优化,不妨看看 01 背包,定义 \(f_j\) 表示在容量不超过 \(j\) 的背包中可以获得的最大价值,有\(f_j=\max\{f_j,f_{j-w_i}+c_i\}\),正好,顺序循环就可以了


for(int i=1; i<=n; ++i)
	for(int j=w[i]; j<=m; ++j)
		f[j]=max(f[j],f[j-w[i]]+c[i]);

多重背包

给定 \(n\) 件物品,每个物品有重量 \(w_{i}\) 和价值 \(c_{i}\),一个物品有 \(s_i\) 件,求容量不超过 \(m\) 的背包最多可以装多少价值物品

定义 \(f_{i,j}\) 表示前 \(i\) 件物品在容量不超过 \(j\) 的背包下可以获得的最大价值,首先考虑像没有优化的完全背包一样暴力枚举取多少件当前物品,有

\[f_{i,j}=\max\{f_{i-1,j},f_{i-1,j-k*w_i}+k*c_i\}, 0\leq k\leq s_i \]

考虑优化,不妨将 \(s_i\) 拆分成 \(\{2^0,2^1,2^2,...,2^{k-1},s_i-2^k+1\}\) 件物品,其中 \(k\) 是满足 \(s_i-2^k+1>0\) 的最大整数,去做 01 背包,这样在凑的途中可以凑出 \([0,s_i]\) 中的正整数

标签:件物品,容量,max,leq,背包,物品
From: https://www.cnblogs.com/chelsyqwq/p/17625704.html

相关文章

  • 完全背包理论基础
    完全背包跟01背包的代码区别就是在第二层背包的遍历的时候是正序的!先遍历物品还是背包是一样的//先遍历物品,再遍历背包privatestaticvoidtestCompletePack(){int[]weight={1,3,4};int[]value={15,20,30};intbagWeight=4;int[]dp=newint[b......
  • 浅谈背包
    引入背包问题,是大多数oier在学习动态规划(下文用dp代替)的过程中,最先接触到的问题。它看似简单,有蕴含着无穷的变化。本文便对作者接触过的背包问题做一个总结。背包问题,一般情况下指:你有\(n\)个物品和一个容量为\(m\)的背包,每个物品有重量\(w\)和价值\(v\),各个物品间可......
  • 背包问题的一些模板
    01背包问题:无优化for(inti=1;i<=n;i++){for(intc=0;c<=m;c++){f[i][c]=f[i-1][c];if(c>=w[i])f[i][c]=max(f[i][c],f[i-1][c-w[i]]+v[i]);}}一维数组优化:for(inti=1;i<=n;i++){for(intc=m;c>=0;c--){......
  • 零一背包与完全背包
    零一背包给定一组物品,每个物品有自己的重量和价值,以及一个背包的容量。目标是选择一些物品放入背包中,使得在不超过背包容量的情况下,背包中物品的总价值最大化。思路1、定义问题dp[i][j]:表示前i个物品中当容量为j时的最大价值2、定义状态转移方程(1) Dp[i][j]=math.max(dp......
  • 多重背包 (单调队列)
    题目链接#include<bits/stdc++.h>usingll=longlong;constintN=1E3+5,M=2E4+5;intn,m;intv[N],w[N],s[N];intf[M];intl,r,q[M];intcalc(inti,intu,intk){ returnf[k*v[i]+u]-k*w[i];}intmain(){ std::ios::sync_with_......
  • 总结: [01背包] 空间优化后内层循环为啥是逆序的?
    总结:[01背包] 空间优化后内层循环为啥是逆序的?首先,这是一个困扰了不少人的问题,虽然网上有挺多的解释,但是有的想起来比较费劲,于是乎,就有了这篇题解题目分析首先,01背包问题是一个非常非常非常经典的动态规划问题(后文简称“动规”或“dp”)。 因为百度百科上的题目分析......
  • [算法学习笔记] 多重背包--二进制拆分
    多重背包回顾一下多重背包是什么?有\(n\)种物品,每个物品都有有限个,每个物品都有重量和价值两个参数,你有一个限重为\(W\)的背包,求背包内价值最大。我们朴素的做法是将多重背包拆分成01背包求解,因为每个物品都有有限个,假设第\(i\)个物品有\(j\)个,那么跑\(j\)次01背包即可。但是这......
  • 完全背包
    二维(一样爆内存)1for(inti=1;i<=n;i++)//完全背包可以重复装相同的物品2for(intj=0;j<=m;j++){3f[i][j]=f[i-1][j];4if(j-v[i]>=0)f[i][j]max(f[i][j],f[i][j-v[i]]+w[i]);5}一维1for(......
  • 背包问题
    引入有n个物品和一个容量为W的背包,每个物品有重量w{i}和价值v{i}两种属性,要求选若干物品放入背包使背包中物品的总价值最大且背包中物品的总重量不超过背包的容量。我们之后涉及到的所有背包问题都会根据这个背景展开1.01背包每个物品只能选取一次。这样每个物品......
  • 背包问题
    (1)01背包01背包二维#include<iostream>#include<algorithm>usingnamespacestd;constintN=1010;intn,m;intv[N],w[N];//v保存体积,w保存价值intf[N][N];//保存所有集合最值状态intmain(){cin>>n>>m;for(inti=1;i<=n......