
背包问题
文章平均质量分 52
DP---背包问题
(xsj)
模拟只会猜题意
贪心只能过样例
DP一般看规律
数论只会gcd
计算几何瞎暴力
图论只会匈牙利
数据结构没学过
字符串只能干输入
展开
-
acwing 734 能量石
题面题解(贪心+01背包)随着时间的流逝,宝石的能量也会随着消失,那么有些宝石的能量就会变成0,我们就不会选择它,那么在最优解中我们就可以删除它,假设剔除完后最优解的排列是a1,a2,a3,a4,a5 …我们设任意两个相邻的位置,ai , ai+1 我们看交换两个能量石的位置会不会使最优解变大 ,交换前 :Ei + Ei+1 - Si * Li+1 ;交换后 :Ei+1 + Ei - Si+1 * Li 。要想按原来的顺序吃能量石,那么就不交换,那么就要求 Ei + Ei+1 - Si原创 2021-03-31 20:03:24 · 193 阅读 · 0 评论 -
acwing 11 背包问题求方案数
题面题解f[i] [j] : 从前 i 个物品中选,体积恰好为 j 的方案价值最大g[i][j] : 从前 i 个物品中选,体积恰好为 j 的取最优解的方案数最后找到最优解的数值,在g[j]g[j]里面只要与这个数相等的都是最优方案数因为最优解不一定是占满背包体积,所以f[m] 不一定是最优解代码#include<iostream>#include<cstdio>#include<string>#include<cstring&原创 2021-03-31 14:59:13 · 104 阅读 · 0 评论 -
acwing 7 混合背包问题
题面题解对于背包问题,我们知道,每层的更新只和上一层有关系,与背包的类型无关,所以我们只需要逐个遍历,遇到什么类型的背包用什么转移方程更新即可代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 1100;int n, m;in原创 2021-03-30 20:30:31 · 133 阅读 · 0 评论 -
acwing 532 货币系统
题面题解若两个货币系统等价,则存在以下性质性质1:a1,a2,a3…an一定可以被表示出来性质2:在最优解中,b1,b2,b3…bm 一定是从a1,a2,a3…an中选出来的性质3: b1,b2,b3…bm一定不能被其他 bi 表示出来我们将a数组从小到大排序(1) 若ai 能被 a0–ai-1 表示,则这个数肯定不在b 数组中(2) 若ai 不能被 a0–ai-1 表示 ,则这个数肯定存在于 b 数组中我们看任意个a0—ai-1 能否表示出 ai ,这样就转原创 2021-03-29 16:41:28 · 145 阅读 · 0 评论 -
acwing 487 金明的预算
题面题解(有依赖的分组背包)我们可以将每一个主件和其附件看作一个物品组,根据题中要求,我们将主件设为a,附件设为1,2 ;那么最多有4中组合 , a , a 1 a 2 a 1 2 ,这四组组合是互斥的,最多只能选择其中的一种,,这样就转化成了分组背包问题在枚举组合的时候,我们可以用2进制枚举,比如 3 (10),那么就表示选择第一个附件,不选第二个附件时间复杂度 物品总数 * 总体积 O(Nm)代码#include<iostream>#includ原创 2021-03-29 11:19:51 · 102 阅读 · 0 评论 -
acwing 1013 机器分配
题面题解(分组背包求具体方案)我们可以把M看成背包的体积,N个公司看成N组,然后每组选几个可以看成各个物品的价值和体积,每组中只能选择一个,这样就完全转化成了分组背包问题了。求具体方案,由于每个公司可以分配不同数量的机器,因此从n遍历到1,假设k为当前公司分配的机器数量,则若满足f[i][j] == f[i - 1][j - k] + w[i][k],其中f[i][j]为当前最优情况,则表示f[i][j]可以从f[i - 1][j - k]状态转移过来,输出当前k值代码#incl原创 2021-03-27 23:09:26 · 174 阅读 · 0 评论 -
acwing 12 背包问题求具体方案
题面题解01背包问题求具体方案数,题目要求所选方案的字典序最小,我们看从1到n的物品中只有3中情况,只能选,则必须选;不能选,则必不选;可选可不选,则必须选,因为从前向后,前面选择的一定比后面的选择好我们可以从后向前,求出当前背包的最大总价值就是 f[1][m]再从第1个物品遍历到第n个物品,其中f[i][j]为当前最优情况,若满足(1) f [ i ] [ j ] == f [ i + 1 ] [ j ] , 则表示f[ i ] [ j ] 是从f [ i +原创 2021-03-27 17:22:19 · 128 阅读 · 0 评论 -
acwing 1023 买书 (完全背包求方案数)
题面题解代码#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int N = 1010;int n;int f[N];int v[5] = {0, 10, 20, 50, 100};int main() { cin >>原创 2021-03-27 16:59:12 · 173 阅读 · 0 评论 -
acwing 278 数字组合
题面题解(求方案数)状态转移方程 :f [ i , j ] = f [ i - 1 ] [ j ] + f [ i ] [ j - v ] (求方案数)初始化 :f [ i ] [ 0 ] = 1 (从前i个物品中选体积是0的方案数是1)f [ 0 ] [ i ] = 0 (从前0个物品中选体积是i的方案数是0)代码#include<bits/stdc++.h>using namespace std;const int N = 1原创 2021-03-27 11:31:46 · 171 阅读 · 0 评论 -
acwing 1020 潜水员
题面题解(二维费用背包)状态表示f[i,j,k]:所有从前i个物品中选,且氧气含量至少是j,氮气含量至少是k的所有选法的气缸重量总和的最小值所有不包含物品i的所有选法:f[i - 1,j,k]所有包含物品i的所有选法:f[i - 1,j - v1,k - v2]注意 :即使所需要的氧气或者氮气所需的是数量是负数,但其所需数量与0是等价的,因此可以通过所需数量为0来转移代码#include<bits/stdc++.h>using namespace std;const原创 2021-03-27 10:35:49 · 165 阅读 · 0 评论 -
acwing 1022 宠物小精灵
题面题解(二维费用01背包)花费1 : 精灵球数量花费2 :皮卡丘体力值价值 :小精灵的数量(每只精灵价值为1)状态表示 :f [ i , j , k ] 表示所有只考虑前i个物品,且花费1不超过 j,花费2不超过k的选法的最大值状态计算:f[ i , j , k ] = Max( f [ i - 1 , j , k ] , f [ i - 1 , j - v1 [ i ],k - v2 [ i ] ] + 1)注意:题目说道:使得皮卡丘体力小于等于0的野生小精灵也原创 2021-03-26 17:01:01 · 173 阅读 · 0 评论 -
P2370 yyy2015c01 的 U 盘 (二分+01背包)
题面题解此题 : 体积不超过S,价值不小于P的情况下选取的物品的最大的体积最小(先输 入大小,后输入价值)01 背包 :在体积不超过v的情况下选取物品的价值最大对于题中有最大的最小值,我们一般采用的是二分,我们发现,选取接口的大小具有单调性,那么我们就可以二分接口的大小,然后判断体积小于等于此接口下选择的物品是否可以满足要求整体思路 :将体积排序,二分体积,然后做一遍01背包看是否满足条件,注意清空 f 数组代码#include<bits/stdc++.h>usi原创 2021-03-25 09:29:33 · 142 阅读 · 0 评论 -
acwing 9 分组背包问题
题面题解分组背包问题: 每组中只能选一个 ,完全背包问题我们的集合划分是对于第i个物品选几个 ,而分组背包问题我们是要枚举第 i 组物品选哪个状态转移方程:和前面01背包一样,都是从i-1层更新,所以一维优化要从后往前更新代码#include<bits/stdc++.h>using namespace std;const int N = 1010;int n, m, cnt;int v[N][N], w[N][N], s[N];int f[N];in原创 2021-03-11 18:03:45 · 166 阅读 · 0 评论 -
acwing 5.多重背包问题 II (二进制优化)
题面题解多重背包优化 :朴素版多重背包是O(nms),看这道题的数据范围肯定会超时不可以用完全背包的方式优化:通过列出式子发现,最后会多出一项,而完全背包的个数是无限的,所以不会多出,f[i][j-v] 的最大值就无法更新f[i][j]二进制优化: 先举个例子,对于第 i 件物品的选取,假设物品的数量有 30 件 ,在不超过背包容量的情况下,我们可以选取0,1,2 … 30 件,这样更新状态方程式的时间复杂度就是O(s) , 神奇的地方来了,我们可以用二进制将这30个数凑出原创 2021-03-11 17:15:32 · 142 阅读 · 0 评论 -
acwing 4 多重背包问题
题面题解多重背包问题:每个物品是有限个代码#include<bits/stdc++.h>using namespace std;const int N = 1010;int n, m;int v[N], w[N], s[N];int f[N][N];int main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> v[i] >>原创 2021-03-11 10:55:01 · 89 阅读 · 0 评论 -
acwing 3 完全背包问题
题面题解完全背包问题 :每个物品可以拿无限次 (只能用DP求最优解,不能用贪心)为什么不能用贪心:我们每次将性价比最高的(价值/体积 最大)放入背包,直到放不下为止,然后继续放性价比次高的 ,这样看似正确,但是贪心只考虑了局部最优解,但是没有办法保证背包的剩余容量最小,无法保证背包的利用价值最大,举个例子,有两种物品 v1=5 w1=21 ,v2=3 w2=12 背包的体积是6 ,用贪心的话先选(21/5=4.2)性价比高的,但是背包容量剩余1,最终价值是21,但是如果选择2的话,可以选两个原创 2021-03-11 10:34:02 · 282 阅读 · 0 评论 -
acwing 2 01背包问题
题面题解代码 #include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int N=1e3+10;int n,m;int v[N],w[N];int f[N][N];int main(){原创 2021-03-10 19:57:46 · 119 阅读 · 1 评论 -
牛客练习赛75 B 小D和他的魔法石(完全背包)
原题链接思路一开始我想着贪心来着,但是比赛时没有写,好像dp更好理解,赛后dp补题先讨论n课树,如果n=2的时候,k就只有两种情况,交换一次(k是奇数),不交换(k是偶数)然后讨论k次交换,如果k>0次的话,肯定是将抗力最小的和魔力最大的变成一组,这样就可以使最终结果最大化,如果 k=0 时,...原创 2021-01-03 11:06:40 · 223 阅读 · 0 评论