动态规划-多重背包问题

Posted 写代码是一种艺术,甚于蒙娜丽莎的微笑!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划-多重背包问题相关的知识,希望对你有一定的参考价值。

0-1背包问题

完全背包问题

多重背包问题是0-1背包问题和完全背包问题的综合体,可以描述如下:从n种物品向容积为V的背包装入,其中每种物品的体积为w,价值为v,数量为k,问装入的最大价值总和?

我们知道0-1背包问题是背包问题的基础,所以在解决多重背包问题的时候,要将多重背包向0-1背包上进行转换。在多重背包问题中,每种物品有k个,可以将每种物品看作k种,这样就可以使用0-1背包的算法。但是,这样会增加数据的规模。因为该算法的时间复杂度为O(V*∑ni=1ki),所以要降低每种物品的数量ki。

九度教程上给出了一种方法,将原数量为k的物品拆分成若干组,每一组可看成一件新的物品,其价值和重量为改组中所有物品的价值重量的总和,每组物品包含的原物品个数分别为:1、2、4...k-2^c+1,其中c为使k-2^c+1大于0的最大整数。这样就将物品数量大大降低,同时通过对这些若干个原物品组合得到的新物品的不同组合,可以得到0到k之间的任意件物品的价值重量和,所以对所有这些新物品做0-1背包,即可得到多重背包的解。转化之后的时间复杂度为O(V*∑ni=1log2(ki))。

九度教程上的一道例题-珍惜现在,感恩生活

题目描述:
为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。请问:你用有限的资金最多能采购多少公斤粮食呢?
输入:
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。
输出:
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
样例输入:
1
8 2
2 100 4
4 100 2
样例输出:
400

编码实现:

#include <stdio.h>
struct Rice{
    int price;
    int weight;
}rice[2001];
 
int max(int a, int b)
{
    return a > b ? a : b;
}
 
int dp_Rice[101];
 
int main()
{
    int nCase;
    scanf("%d", &nCase);
    while (nCase--)
    {
        int sumMoney, speRice;
        scanf("%d%d", &sumMoney, &speRice);
        int index = 0;
        int pr, wei, num;
        for (int i = 1; i <= speRice; i++)
        {
            scanf("%d%d%d", &pr, &wei, &num);
            int k = 1;
            while (num - k>0)
            {
                num -= k;
                rice[++index].price = pr*k;
                rice[index].weight = wei*k;
                k *= 2;
            }
            rice[++index].weight = wei*num;
            rice[index].price = pr*num;
        }
 
        for (int j = 0; j <= sumMoney; j++)
            dp_Rice[j] = 0;
        for (int i = 1; i <= index;i++)
        for (int j = sumMoney; j >= rice[i].price; j--)
            dp_Rice[j] = max(dp_Rice[j],dp_Rice[j-rice[i].price]+rice[i].weight);
 
        printf("%d\\n",dp_Rice[sumMoney]);
    }
    return 0;
 
}
/**************************************************************
    Problem: 1455
    User: 凌月明心
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1036 kb
****************************************************************/

以上是关于动态规划-多重背包问题的主要内容,如果未能解决你的问题,请参考以下文章

动态规划问题3--多重背包

动态规划-多重背包问题

动态规划多重背包问题

动态规划背包问题总结:01完全多重与其二进制优化分组背包 题解与模板

动态规划入门——经典的完全背包与多重背包问题

动态规划——背包问题python实现(01背包完全背包多重背包)