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


    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
    ",dp_Rice[sumMoney]);
        }
        return 0;
     
    }
    /**************************************************************
        Problem: 1455
        User: 凌月明心
        Language: C++
        Result: Accepted
        Time:10 ms
        Memory:1036 kb
    ****************************************************************/
  • 相关阅读:
    汽车知识图谱
    医疗知识图谱与自动问答
    MongoDB(单节点)环境配置
    【字符串-01】
    【双指针-01】
    【排序-01】十大排序算法(Python实现)
    【队列-01】队列题目解析
    【栈-01】栈题目解析
    【贪心-02】贪心算法题目解析
    【贪心-01】贪心算法原理介绍
  • 原文地址:https://www.cnblogs.com/tgycoder/p/5329424.html
Copyright © 2020-2023  润新知