zoukankan      html  css  js  c++  java
  • 题解【AcWing487】金明的预算方案

    题面

    有依赖的背包问题模板题。

    我们观察到 每个主件可以有 0 个、1 个或 2 个附件

    于是考虑对于每一个主件,我们用枚举子集的方式枚举使用哪一些附件,

    然后就是一个经典的分组背包问题了。

    注意背包问题一般是先枚举物品,再枚举体积,最后枚举决策。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef pair <int, int> PII;
    typedef pair <int, PII> PIII;
    
    int n, m, ans, dp[32003];
    vector <PIII> mas; //存储每一个主件
    vector <PII> att[66]; //存储每一个主件的附件
    
    int main()
    {
        cin >> m >> n;
        //m 为最大价格,n 为物品个数
        for (int i = 1; i <= n; i+=1)
        {
            int v, w, q;
            cin >> v >> w >> q;
            if (!q) 
                mas.push_back(make_pair(i, make_pair(v, v * w))); //这个物品是主件,就保存它的编号、价格和价值
            else 
                att[q].push_back(make_pair(v, v * w)); //附件就存储它的价格和价值
        }
        int fst = mas.size(); //有多少个主件
        for (int i = 0; i < fst; i+=1) //枚举每一个主件(分组背包问题中的组数)
        {
            for (int j = m; j >= 0; j-=1) //枚举体积
            {
                int bh = mas[i].first, jiage = mas[i].second.first, jiazhi = mas[i].second.second;
                //分别存储当前枚举到的主件的编号、价格和价值
                int fj_gs = att[bh].size(); //当前主件的附件个数
                for (int k = 0; k < (1 << fj_gs); k+=1) //枚举子集
                {
                    int v = jiage, w = jiazhi; //存储现有的价格和价值
                    for (int l = 0; l < fj_gs; l+=1) //枚举每个附件
                        if (k >> l & 1) //如果要选择这个附件
                            v += att[bh][l].first, w += att[bh][l].second; //加上这个附件的价值和价格
                    if (j >= v) dp[j] = max(dp[j], dp[j - v] + w); //这种方案合法就进行转移
                }
            }
        }
        cout << dp[m] << endl; //输出最大价值
        return 0;
    }
    
  • 相关阅读:
    Fast Member
    C++箴言:理解typename的两个含义
    网上资源工具
    WeakReference
    MonoGame教程
    The RAII Programming Idiom
    OpenGL Common Mistakes
    Finalize()、Dispose()、SafeHandle、GC
    Interop with Native Libraries
    C++计算几何库
  • 原文地址:https://www.cnblogs.com/xsl19/p/12335844.html
Copyright © 2011-2022 走看看