AcWing 487. 金明的预算方案 (有依赖关系的背包问题)

简介: 笔记

题意


金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。


更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。


今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:13.png

如果要买归类为附件的物品,必须先买该附件所属的主件。


每个主件可以有0个、1个或2个附件。


附件不再有从属于自己的附件。


金明想买的东西很多,肯定会超过妈妈限定的N元。


于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。


他还从因特网上查到了每件物品的价格(都是10元的整数倍)。


他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。


设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j 1 , j 2 , … , j k ,则所求的总和为:


v [ j 1 ] ∗ w [ j 1 ] + v [ j 2 ] ∗ w [ j 2 ] + … + v [ j k ] ∗ w [ j k ] (其中*为乘号)


请你帮助金明设计一个满足要求的购物单。


思路

分组背包


先把所有主件存起来 然后把每个主件对应的副件存在一个 vector 中


对每个物品遍历 如果它是主件的话 就枚举一下取哪些它的副件 这里可以用二进制枚举


最后求出最大值即可


代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 998244353
#define endl '\n'
#define int long long
using namespace std;
inline int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
inline int lowbit(int x) { return x & -x; }
typedef long long LL;
typedef pair<int, int>PII;
const int N = 70;
int n, m;
PII master[N]; //主件
vector<PII>servent[N]; //主件下面的附件
int f[32050];
void solve() {
  cin >> m >> n;
  for (int i = 1; i <= n; ++i) {
    int v, w, q; cin >> v >> w >> q;
    if (q == 0) {
      master[i] = { v,v * w };
    }
    else servent[q].push_back({ v,v*w });
  }
  for (int i = 1; i <= n; ++i) {
    if (master[i].first) { //如果是一个主件
      for (int j = m; j >= 0; --j) {
        for (int k = 0; k < 1 << servent[i].size(); ++k) {
          int v = master[i].first;
          int w = master[i].second;
          for (int t = 0; t < servent[i].size(); ++t) {
            if ((k >> t) & 1) {
              v += servent[i][t].first;
              w += servent[i][t].second;
            }
          }
          if (j >= v)f[j] = max(f[j], f[j - v] + w);
        }
      }
    }
  }
  cout << f[m] << endl;
}
signed main() {
  //int t; cin >> t;
  //while(t--)
  solve();
  return 0;
}


目录
相关文章
|
算法
分组背包问题与背包问题求具体方案(二)
AcWing算法提高课内容,本文讲解 动态规划
235 0
分组背包问题与背包问题求具体方案(二)
|
算法
分组背包问题与背包问题求具体方案(一)
AcWing算法提高课内容,本文讲解 动态规划
233 0
分组背包问题与背包问题求具体方案(一)
|
4月前
|
C语言
末谈背包问题求具体方案
末谈背包问题求具体方案
|
机器学习/深度学习
【背包问题の第五讲】强化利用「等差」特性推导「完全背包」的核心要素
【背包问题の第五讲】强化利用「等差」特性推导「完全背包」的核心要素
|
9月前
|
存储 算法 Java
【算法设计与分析】— —实现活动安排问题的贪心算法。
【算法设计与分析】— —实现活动安排问题的贪心算法。
|
存储 数据安全/隐私保护 C++
C++程序设计-第13周递归函数及银行系统程序设计上机实践项目
回到课程主页,链接:C++程序设计课程主页-2012级   本次上机对应的教学内容:第4章   递归函数、变量的作用域、存储类型 第一部分 练习+上机验证(不必提交上机报告)   阅读下列程序,写出程序的运行结果。上机时运行程序,与你的预期进行对照、理解。   提示:如果对运行结果不理解,请通过单步执行的手段跟踪理解。  1. 两个有递归函数的程序,要求按课堂演示,画出调用过程(1) #i
1273 0
|
算法
猴子排序的期望复杂度推导(雾)
  众所周知,猴子排序打破了排序算法$O(n\log{n})$的桎梏(雾),具体的话,显然最好情况一次成功就是$O(n)$,最坏情况那就$O(+\infty)$了。期望是多少呢?让我来推导一番(逃)。   首先,设序列长度为$n$,每次打乱序列和检测是否有序为$O(n)$,每次成功的概率为$\frac{1}{n!}$(全排列共$n!$种),失败的概率为$1-\frac{1}{n!}$。
1601 0
|
9月前
|
算法 Python
动态规划法在汽车租赁问题中的实战(使用策略迭代法得到最优策略和最优价值 python实现 附源码)
动态规划法在汽车租赁问题中的实战(使用策略迭代法得到最优策略和最优价值 python实现 附源码)
104 0
|
机器学习/深度学习
【组合数学】组合数学简介 ( 组合思想 2 : 数学归纳法 | 数学归纳法推广 | 多重归纳思想 )
【组合数学】组合数学简介 ( 组合思想 2 : 数学归纳法 | 数学归纳法推广 | 多重归纳思想 )
257 0
【组合数学】组合数学简介 ( 组合思想 2 : 数学归纳法 | 数学归纳法推广 | 多重归纳思想 )

热门文章

最新文章