参考资料:https://blog.csdn.net/qq_37702890/article/details/80037289
01背包原型:
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是v[i]。求将哪些物品装入背包可使价值总和最大。
核心代码:
for(int i=0;i<N;i++) //枚举物品
for(int j=V;j>=c[i];j--)
//枚举体积,逆序枚举,否则变成完全背包
dp[j]=max(dp[j],dp[j-c[i]]+v[i]);
问题1:HDU2546 饭卡
题意:有五块钱就能打菜,给定n和n个菜的价格以及卡上余额,求如何可以使得卡上余额最小。
对应:菜——物品
☆菜的价格——费用、价值
余额——容量
思路:0.输入数据,清零数组,判断余额有没有五块钱,没有就直接输出即可
1.取出5块钱,我们用这5块钱去买最贵的东西
2.用剩下的钱作为背包容量去套用01背包模板
3.输出数据,记得加上5块钱买的最贵的东西
问题2:HDU1171:Big Event in HDU
题意:给定一些物品的价格和数量,分成两份。
思路:0.整体思路为往“背包”里装价值为总价一半的物品
1.将这些物品价格存入数组,重复的需要重复存,顺便算出总价
2.套用01背包即可
问题3:HDU2603 Bone Collector
题意:给定骨头的大小和骨头的价值,求给定背包容量下,求能装的东西的最大价值
思路:直接套用01背包即可
问题4:HDU2639:Bone Collector II
题意:给定骨头的大小和骨头的价值,求给定背包容量下,求能装的东西的第k大价值
思路:0.dp数组增加一维 [k] 去存储第k优解的值
1.同样是01背包,但是这次不能够取最大值,因此,我们增加一个k次循环,和两个数组存储在给定背包情况下可能出现的所有价值
2.合并两个数组(去重)。用-1去标记末端的值,反复比较两数组的最大元素(其实这两个数组是从大到小依次的),将它们放入dp数组内即可