这道题可以用分组背包来做。

但是分组有两种方式

一种是把主件,主件+附件1,主件+附件2分成一组

组内只能选一个物品

一种是建一颗树,用树形dp的方式去做

第二种更通用,就算物品的依赖关系是森林都可以做

而第一种只限于这道题,因为只有一层关系,所以有特殊解

目前只写了第一种,后面补第二种

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #define REP(i, a, b) for(int i = (a); i < (b); i++)
  6. using namespace std;
  7. const int MAXN = 412;
  8. const int MAXM = 32123;
  9. int f[MAXM], p[MAXN], w[MAXN], fa[MAXN], n, m;
  10. int W[MAXN], P[MAXN], k[MAXN], cnt, N;
  11. void add(int w, int p)
  12. {
  13. W[N] = w; P[N] = p; k[N++] = cnt;
  14. }
  15. void init()
  16. {
  17. REP(i, 1, n + 1)
  18. if(fa[i] == 0)
  19. {
  20. add(w[i], p[i]);
  21. vector<int> son;
  22. REP(j, 1, n + 1)
  23. if(fa[j] == i)
  24. son.push_back(j);
  25. if(son.size() >= 1) add(w[i] + w[son[0]], p[i] + p[son[0]]);
  26. if(son.size() >= 2)
  27. {
  28. add(w[i] + w[son[1]], p[i] + p[son[1]]);
  29. add(w[i] + w[son[1]] + w[son[0]], p[i] + p[son[1]] + p[son[0]]);
  30. }
  31. cnt++;
  32. }
  33. }
  34. int main()
  35. {
  36. scanf("%d%d", &m, &n);
  37. REP(i, 1, n + 1)
  38. {
  39. scanf("%d%d%d", &w[i], &p[i], &fa[i]);
  40. p[i] *= w[i];
  41. }
  42. init();
  43. REP(r, 0, cnt)
  44. for(int j = m; j >= 0; j--)
  45. REP(i, 0, N)
  46. if(k[i] == r && j - W[i] >= 0)
  47. f[j] = max(f[j], f[j - W[i]] + P[i]);
  48. printf("%d\n", f[m]);
  49. return 0;
  50. }

第二种

大家有没有看到这个代码和选课的树形dp的区别。(选课https://blog.csdn.net/qq_34416123/article/details/82258060

这道题是选课的简化版,最多只有两个儿子,而且只有三层。

这份代码多了个递归参数体积。选课那题体积都为1,而cnt数组记录的是以i结尾的子树

的节点的个数,也就是体积。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<vector>
  4. #define REP(i, a, b) for(int i = (a); i < (b); i++)
  5. #define FOR(i, a, b) for(int i = (a); i <= (b); i++)
  6. using namespace std;
  7. const int MAXN = 112;
  8. const int MAXM = 32123;
  9. int f[MAXN][MAXM], p[MAXN], w[MAXN], n, m;
  10. vector<int> g[MAXN];
  11. void dfs(int u, int k)
  12. {
  13. REP(i, 0, g[u].size())
  14. {
  15. int v = g[u][i];
  16. FOR(j, 0, k - w[v]) f[v][j] = f[u][j];
  17. if(k >= w[v]) dfs(v, k - w[v]);
  18. FOR(j, w[v], k) f[u][j] = max(f[u][j], f[v][j-w[v]] + w[v] * p[v]);
  19. }
  20. }
  21. int main()
  22. {
  23. scanf("%d%d", &m, &n);
  24. FOR(i, 1, n)
  25. {
  26. int fa;
  27. scanf("%d%d%d", &w[i], &p[i], &fa);
  28. g[fa].push_back(i);
  29. }
  30. dfs(0, m);
  31. printf("%d\n", f[0][m]);
  32. return 0;
  33. }

P1064 金明的预算方案 (依赖性背包问题)的更多相关文章

  1. 洛谷 P1064 金明的预算方案(01背包问题)

    传送门:Problem 1064 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 这道题是 “01”背包问题的变形. 如果不考虑买附件必 ...

  2. 有依赖的背包---P1064 金明的预算方案

    P1064 金明的预算方案 solution 1 暴搜 70pt dfs (当前搜到了第几个物品,产生的总价值,剩下多少钱) 剪枝 1:如果剩下的钱数<0,直接return就好,没必要继续了 剪 ...

  3. 【dp】P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...

  4. 洛谷 P1064 金明的预算方案(有依赖的背包问题)

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...

  5. 洛谷 P1064 金明的预算方案【有依赖的分组背包】

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱 ...

  6. P1064 金明的预算方案 (分组背包稍稍变形)

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...

  7. 洛谷P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...

  8. luogu P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...

  9. 洛谷 P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...

  10. 洛谷 P1064 金明的预算方案 (有依赖的0/1背包)

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...

随机推荐

  1. [读书笔记] R语言实战 (六) 基本图形方法

    1.  条形图 barplot() #载入vcd包 library(vcd) #table函数提取各个维度计数 counts <- table(Arthritis$Improved) count ...

  2. 炫酷 CSS 背景效果的 10 个代码片段

    在现代网页设计中,大背景图设计非常流行.随着高清(现在是4K)显示器的出现,越来越多的网页设计师使用大背景图来填充屏幕. 因为这样可以造成很大的视觉冲击力,并有助于更好的传递所要表现的内容. 但是,如 ...

  3. oracle 数据类型及函数

    第一节:字符串类型及函数 字符类型分 3 种,char(n) .varchar(n).varchar2(n) : char(n)固定长度字符串,假如长度不足 n,右边空格补齐: varchar(n)可 ...

  4. [Hyperapp] Interact with the State Object through Hyperapp Action functions

    Hyperapp is an ultra lightweight (1kb), minimal, functional, JavaScript library for building UIs. It ...

  5. c#将List&lt;T&gt;转换成DataSet

    /// <summary>         /// List<T> 转换成DataSet         /// </summary>         /// &l ...

  6. Codeforces 10A-Power Consumption Calculation(模拟)

    A. Power Consumption Calculation time limit per test 1 second memory limit per test 256 megabytes in ...

  7. 如何获取Assets的路径

    有两种方法可以获取assets的绝对路径: 第一种方法: String path = file:///android_asset/文件名; 第二种方法: InputStream abpath = ge ...

  8. CoreData 从入门到精通(二) 数据的增删改查

    在上篇博客中,讲了数据模型和 CoreData 栈的创建,那下一步就是对数据的操作了.和数据库一样,CoreData 里的操作也无非是增删改查.下面我们将逐步讲解在 CoreData 中进行增删改查的 ...

  9. [NOIP2017] 逛公园 解题报告(DP)

    我很不想说 在我的AC代码上我打了表,但实在没有办法了.莫名的8,9个点RE.然而即便是打表...也花了我很久. 这大概是NOIP2017最难的题了,为了让不懂的人更容易理解,这篇题解会比较详细 我的 ...

  10. JavaScript中Number常用属性和方法

    title: JavaScript中Number常用属性和方法 toc: false date: 2018-10-13 12:31:42 Number.MAX_VALUE--1.79769313486 ...