• 混合背包


    题目链接:https://www.acwing.com/problem/content/7/

    思路:

    如果将前面三个背包混合起来,也就是说,有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包),应该怎么求解呢?

    01背包与完全背包的混合
    考虑到在01背包和完全背包中给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类物品可以取无限次,那么只需在对每个物品应用转移方程时,根据物品的类别选用顺序或逆序的循环即可,复杂度是O(VN)。

    再加上多重背包
    如果再加上有的物品最多可以取有限次,用多重背包中将每个这类物品分成O(log(p[i]))个01背包的物品的方法也已经很优了。当然,更清晰的写法是调用我们前面给出的三个相关过程。代码:

    struct Node {
        int kind;
        int v,w;
    };
    
    std::vector<Node> vec;
    
    int dp[1010];
    
    int main() {
        int n,m;
        std::cin >> n >> m;
        for (int i = 1;i <= n;i++) {
            int v,w,s;
            std::cin >> v >> w >> s;
            if (s == -1) {
                vec.push_back({-1,v,w});
            }
            else if (s == 0) {
                vec.push_back({0,v,w});
            }
            else {
                for (int k = 1;k <= s;k <<= 1) {
                    s -= k;
                    vec.push_back({-1,v*k,w*k});
                }
                if (s)
                    vec.push_back({-1,v*s,w*s});
            }
        }
        for (auto i:vec) {
            if (i.kind == -1) {
                for (int j = m;j >= i.v;j--)
                    dp[j] = std::max(dp[j],dp[j-i.v]+i.w);
            }
            else {
                for (int j = i.v;j <= m;j++) {
                    dp[j] = std::max(dp[j],dp[j-i.v]+i.w);
                }
            }
        }
        std::cout << dp[m] << std::endl;
        return 0;
    }
  • 相关阅读:
    webstock学习
    H5存储
    js保留两位小数
    html5拖动滑块
    js判断网页访问设备类型
    关于hadoop setCombinerClass 与 setReducerClass同时使用存在的问题。
    hadoop 输出中文乱码问题
    mapreduce实现学生平均成绩
    mapreduce 实现数子排序
    hadoop mapreduce实现数据去重
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12250553.html
Copyright © 2020-2023  润新知