![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
背包问题
abant2
世界上最菜的arcem
展开
-
acwing 2 普通背包 2维做法的坑
接下来看二维的做法,首先讲一下,为什么需要二维的做法,因为一维无法满足部分题目的条件,比如说,如果需要我们找到放进背包具体是哪几个物品,一维的是无法保存历史信息的,在这个例子下我们就需要保存二维矩阵,再进行回溯。了,我们也不能跳出循环(这个会多消耗一些时间,但影响不大)而是要把上面的结果复制下来,算是和一维最重要的区别了。这个定义非常的巧妙并且很难直接想到,因此,很多dp题目会以背包作为变种,因此,背包是dp中非常经典的例子。首先看一维的做法,如下所示,比较简单,注意细节:在内层循环中,如果。原创 2023-02-15 18:14:44 · 329 阅读 · 0 评论 -
leetcode 2218 分组背包
此题只能从上往下挖,可以将每个坑看做一个组,从而转化为分组背包问题,即每组最多取一个物品。我们将其转化为01背包的思路,dp[i][j]dp[i][j]dp[i][j] 表示前 iii 组物品在容量为 jjj 的背包中得到的最大价值。由于每组最多之恶能选一个,如果不选,则dp[i][j]=dp[i−1][j−1]dp[i][j] = dp[i-1][j-1]dp[i][j]=dp[i−1][j−1]如果选的话,只能选其中一个,我们需要枚举每一个物品的 www 和 vvv,dp[i][j]=max(dp.原创 2022-04-01 16:49:22 · 4812 阅读 · 0 评论 -
LCP 47 困住无辜的人 背包装满方案数
此题的队列是完全没用的数据结构,栈的作用是困住无辜的人,容量为 bbb 的栈,会困住 b−1b-1b−1 个无辜的人,所以我们需要把数组中每个数减一,然后看他们如何拼满 kkk 个人。此题最重要的是进行题目解析,减一后转换为背包装满问题就很简单了。之前比赛时压力比较大,理解为从 nnn 个物品中做选择,如果选 mmm 个,求出能装满容量为 m+km+km+k 的背包的方案数。其实就每个减一就行,但是脑子没有转过弯,就很难受。class Solution {public: int secur.原创 2022-03-24 15:50:43 · 860 阅读 · 0 评论 -
leetcode 2212 二维01背包回溯
此题要射箭,而且必须比Bob多一支,所以如果决定了要射哪个靶子,那要射的箭的数目是一定的。所以,我们可以将这个问题转化为01背包问题。注意,此题需要做回溯,而背包做回溯和最长上升子序列不一样,是需要存二维数组然后回溯的。我们应该知道,一维01背包是由二维背包转化而来的。背包问题的核心是选或者不选,dp[i][j]dp[i][j]dp[i][j] 表示前i个物品的最佳组合在容量为 jjj 的背包中取得的最大价值,即dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]+v[i]).原创 2022-03-24 14:52:08 · 211 阅读 · 0 评论 -
leetcode 377 组合总和4 背包装满问题 不同顺序方案个数
这个题是相当的神奇,相对于背包装满问题的方案个数,需要将两个循环的位置进行交换。和完全背包和01背包的关系有些相似,代码如下:typedef unsigned long long ll;class Solution {public: int combinationSum4(vector<int>& nums, int target) { ll dp[target+1]; memset(dp, 0, sizeof(dp)); d原创 2021-04-27 19:41:22 · 139 阅读 · 0 评论 -
多重背包问题
解法一:转化为01背包问题,直接把k个物品放置k次即可。#include <bits/stdc++.h>using namespace std;int main(){ int N, W; scanf("%d %d", &N, &W); int dp[W+1]; memset(dp, 0, sizeof(dp)); for(int i=0;i<N;i++) { int v, w, s;原创 2021-04-26 19:42:12 · 70 阅读 · 0 评论