首页 > 其他分享 >AcWing 5. 多重背包问题 II

AcWing 5. 多重背包问题 II

时间:2023-12-04 11:12:25浏览次数:26  
标签:背包 log int II goods sim AcWing

题面:
有 \(N\) 件物品和一个容量是 \(V\) 的背包。
第 \(i\) 件物品最多有 \(s_i\) 件,每件体积是 \(v_i\),价值是 \(w_i\)。
求解将哪些物品装入背包,可使这些物品的体积总和不超过背包容量,且价值总和最大
输出最大价值。

原题链接:5. 多重背包问题 II - AcWing

先前的思路[1]:将 \(s\) 个物品分成 \(s\) 份

由此转换为 \(s\) 个 01背包问题,例如 7 就可以拆解为 1 1 1 1 1 1 1

二进制优化思路:将 \(s\) 个物品分成 \(log(s)\) 份

\(2^0+2^1+2^2=1+2+4=7\)
实际上,就像每一个小于等于 7 的数都可以通过 1 2 4 这三个数字组合出来一样,
最少需要 \(ceil(\log_{2}{s})\) 个数,就可以组合出 \(0 \sim s\) 之间的所有数。

对于 \(s\) 不属于 \(2^n-1\) 的情况,将 \(s-\sum_{i=0}^{[\log_{2}{s}]} 2^i\) 作为第 \(ceil(\log_{2}{s})\) 个数即可。
例如,对于 \(10\),就可以拆解为1 2 4 3。既然每一个 \(0\sim 7\) 之间的数都可以通过 1 2 4 组合出来,那么它们加上 \(3\) 就可以表示 \(0\sim 10\) 之间的数。

时间复杂度:\(O(n^3)\) → \(O(n^2logn)\)

#include <bits/stdc++.h>
using namespace std;

const int N = 2010;
int n, m, f[N];

struct good {
	int v, w;
};

int main()
{
	vector<good> goods;
	cin >> n >> m;
	//拆堆
	for (int i = 0; i < n; i++) {
		int v, w, s;
		cin >> v >> w >> s;
		for (int j = 1; j <= s; j *= 2) {
			s -= j;
			goods.push_back({ v * j, w * j });
		}
		if (s > 0)	goods.push_back({ v * s, w * s });
	}
	//01板子
	for (auto g : goods)
		for (int j = m; j >= g.v; j--)
			f[j] = max(f[j], f[j - g.v] + g.w);
	cout << f[m];
}

  1. https://www.acwing.com/activity/content/code/content/7361624/) ↩︎

标签:背包,log,int,II,goods,sim,AcWing
From: https://www.cnblogs.com/haruhomu/p/17874460.html

相关文章

  • AcWing 3. 完全背包问题
    题面:有\(N\)种物品和一个容量是\(V\)的背包,每种物品都有无限件可用。第\(i\)种物品的体积是\(v_i\),价值是\(w_i\)。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。原题链接:3.完全背包问题-AcWing根据01背包的思路扩......
  • AcWing 2. 01背包问题
    题面:有 \(N\) 件物品和一个容量是 \(V\) 的背包。每件物品只能使用一次。第 \(i\) 件物品的体积是 \(v_i\),价值是 \(w_i\)。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。原链接:2.01背包问题-AcWing有限集的最优问......
  • Acwing第132场周赛
    AcWing5366.大小写转换#include<bits/stdc++.h>#definelsp<<1#definersp<<1|1#definePIIpair<int,int>#definelllonglong#definedbdouble#defineullunsignedlonglong#defineendl'\n'#defineioios::sync_with_......
  • SP1716 GSS3 - Can you answer these queries III 题解
    题意:给定一个长度为$n$的序列$a$,$q$次操作,每次操作为以下之一:\(0\)\(x\)\(y\):将\(a_x\)修改为\(y\)\(1\)\(l\)\(r\):询问区间\([l,r]\)的最大连续子序列和思路:考虑线段树维护区间最大连续子序列和:线段树每个节点需要维护的信息:区间左端点$l$,区......
  • 前缀和/差分——acwing算法基础课笔记
    个人笔记,欢迎补充,指正。一维前缀和对于数组:a[1],a[2],a[3]...a[n];其前缀和数组为s[i]=a[1]+a[2]+...+a[i];下标必须从1开始求前缀和1for(inti=1;i<n;++i)2s[i]=s[i-1]+a[i];s[0]需要定义为0作用求原数组里一段数(l,r)的和......
  • 背包问题
    先聊聊区分贪心和01背包背包问题:有多个物品,重量不同、价值不同,以及一个容量有限的背包,选择一些物品装到背包中,问怎么裝才能使装进背包的物品总价值最大。根据不同的限定条件,可以把背包问题分为很多种,常见的有下面两种:(1)如果每个物体可以切分。称为一般背包问题,用贪心法求......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 19.删除链表的倒数第N个节
    LeetCode24.两两交换链表中的节点题目链接:LeetCode24思路:交换结点前将cur后第一个结点和第三个结点进行保存,然后修改cur指向头节点后再修改头节点后的结点classSolution{public:ListNode*swapPairs(ListNode*head){ListNode*dummyHead=newListNo......
  • Acwing.第132场周赛
    Acwing.第132场周赛比赛地址A.大小写转换题目思路:简单的模拟,可以使用c++大小写转换库函数,但是由于我早上比赛时候没用好就不敢用了就用了ASCII码转换代码:#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ strings; cin>>s; for(inti=0;i<s.size();i++)......
  • 如何优雅的关闭一个IIS站点
    众所周知,当我们使用IIS的时候,在使用负载均衡的情况下,想停掉一个站点,通常会点击Sites(网站)中的Stop(停止)来停止一个站点。但是这样做,会带来一个问题,当点击Stop(停止)时,正在响应中的请求会立刻被切断,使客户端无法收到响应,后续也无法连接该站点,在某些业务场景中,比如涉及金额交易业务,在没......
  • #yyds干货盘点# LeetCode程序员面试金典:下一个更大元素 II
    题目给定一个循环数组nums(nums[nums.length-1]的下一个元素是nums[0]),返回nums中每个元素的下一个更大元素。数字x的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1。 ......