01背包问题刷题总结

参考资料: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数组内即可



         

猜你喜欢

转载自blog.csdn.net/gg9002/article/details/81044591
今日推荐