zoukankan      html  css  js  c++  java
  • 动态规划5-多重背包

    有一个背包容积是v,有n种物品,第i种物品的体积是vi,重量是wi,最多mi个,求如何放入物品可以使背包装入的重量最重。

    这个与完全背包非常相似了,唯一的区别是个数,我们只需要在遍历个数循环的时候再加一个条件判断即可。

    vector<int> nums = { 2, 3, 2, 1, 4 };
    void zobag(vector<int>& weights, vector<int>& wealths, int vbag, int index, map<int, int>& selmap)
    {
        if (index < 0)
        {
            return;
        }
        else
        {
            map<int, int> selmap2 = selmap;
            for (int i = 0; i <= vbag / weights[index]; i++)
            {
                map<int, int> selmap1 = selmap;
                if (vbag >= i * weights[index] && i <= nums[i])
                {
                    selmap1[index] = i;
                }
                zobag(weights, wealths, vbag - i * weights[index], index - 1, selmap1);
                int tmp1 = 0;
                int tmp2 = 0;
                //int tmpw1 = 0;
                for (auto& iter : selmap1)
                {
                    int a = iter.second;
                    while (a > 0)
                    {
                        tmp1 += wealths[iter.first];
                        //tmpw1 += weights[iter.first];
                        a--;
                    }
                }
                for (auto& iter : selmap2)
                {
                    int a = iter.second;
                    while (a > 0)
                    {
                        tmp2 += wealths[iter.first];
                        a--;
                    }
                }
                /*if (tmpw1 != 10)
                {
                    tmp1 = 0;
                    selmap1.clear();
                }*/
                if (tmp1 > tmp2)
                {
                    selmap2 = selmap1;
                }
            }
            selmap = selmap2;
        }
    }
    int main()
    {
        int vbag = 10;
        vector<int> weights = { 5, 3, 4, 3, 5 };
        vector<int> wealths = { 500, 200, 300, 350, 400 };
        map<int, int> selmap;
        zobag(weights, wealths, vbag, weights.size() - 1, selmap);
        for (auto& iter : selmap)
        {
            int a = iter.second;
            while (a > 0)
            {
                cout << iter.first << endl;
                a--;
            }
        }
        char inchar;
        cin >> inchar;
    }
    int main()
    {
        int vbag = 10;
        vector<int> weights = { 5, 3, 4, 3, 5 };
        vector<int> wealths = { 500, 200, 300, 350, 400 };
        vector<int> nums = { 2, 3, 2, 1, 4 };
        int* dp = new int[(10 + 1) * 5]();//多一个,方便用索引直接表示内容
        int maxdp = 0;
        int maxi = 0;
        int maxj = 0;
        for (int vbgi = 0; vbgi < 10 + 1; vbgi++)
        {
            for (int i = 0; i < 5; i++)
            {
                if (vbgi == 0)
                {
                    *(dp + vbgi * 5 + i) = 0;
                }
                else
                {
                    int optw = 0;
                    int wi = 0;
                    while (vbgi >= weights[i] * wi && wi <= nums[i])
                    {
                        int tmpoptw = wealths[i] * wi;
                        if (i - 1 >= 0)
                        {
                            tmpoptw = tmpoptw + *(dp + (vbgi - weights[i] * wi) * 5 + i - 1);
                        }
                        if (tmpoptw > optw)
                        {
                            optw = tmpoptw;
                        }
                        wi++;
                    }
                    if (optw > maxdp)
                    {
                        maxdp = optw;
                        maxi = i;
                        maxj = vbgi;
                    }
                    //这里注意赋值
                    *(dp + vbgi * 5 + i) = optw;
                }
            }
        }
        while (*(dp + maxj * 5 + maxi) > 0 && maxi >= 0 && maxj >= 0)
        {
            //这里需要遍历找到第一个满足的条件,因为后面的会取前面的最大值
            for (int i = 0; i < maxi; i++)
            {
                if (*(dp + maxj * 5 + i) == *(dp + maxj * 5 + maxi))
                {
                    maxi = i;
                    break;
                }
            }
            //这里注意从1开始遍历,因为表示装了几个
            for (int i = 1; i <= *(dp + maxj * 5 + maxi) / wealths[maxi]; i++)
            {
                cout << wealths[maxi] << endl;
            }
            maxj = maxj - *(dp + maxj * 5 + maxi) / wealths[maxi] * weights[maxi];
            maxi--;
        }
        char inchar;
        std::cin >> inchar;
    }
  • 相关阅读:
    [NOI2019]回家路线(最短路,斜率优化)
    LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)
    Codeforces Global Round 4 题解
    CF908G New Year and Original Order(DP,数位 DP)
    [BJOI2019]光线(DP)
    CF1194F Crossword Expert(数论,组合数学)
    SPOJ31428 FIBONOMIAL(斐波那契数列)
    Codeforces Round 573 (Div.1) 题解
    [THUPC2018]弗雷兹的玩具商店(线段树,背包)
    数学基础
  • 原文地址:https://www.cnblogs.com/studywithallofyou/p/12191523.html
Copyright © 2011-2022 走看看