九大背包问题专题--有依赖的背包问题(树形Dp结合)
9.有依赖的背包问题
问题:
有N件物品和一个容量是V的背包。
物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
如图所示
如果选择物品5,则必须选择物品1和2,这是因为2是5的父节点,1是2的父节点。
每件物品的编号是i,体积是vi,价值是wi,依赖的父节点编号是pi。物品的下标范围是1…N.
求解将哪些物品装入背包,可使这些物品的总体积不超过背包的容量,且价值总和最大。
输出最大价值
输入格式
第一行有两个整数,N,V,用空格隔开,分别表示物品个数、背包容量。
接下来有N行,每行数据表示一个物品
第i行有三个整数vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果pi=-1,表示根节点,数据保证所有物品构成一棵树。
输出格式
输出一个整数,表示最大价值
数据范围
1<N,V<=100
0<vi,wi<=100
父节点编号范围:
内部节点:1<=pi<=N;
根节点:pi=-1;
输入样例
5 7
2 3 -1
2 2 1
3 5 1
4 7 2
3 6 2
输出样例
11
分析思路:
背包和树形Dp结合(转化为分组背包问题)
每个结点,把它们对应的子节点都递归计算一下,算出每个子节点不同体积下的最大价值;,每个子节点都是一个物品组,不同体积对应到不同组;整个组里面只能选择一个物品
f[i][j]表示选结点i的情况下,所用的体积是j的情况下,以i为根的整棵子树的最大价值是多少
从上往下递归求解,每做完一个结点,先把它的所有子节点的f[i][j]都算出,每个子节点对应在不同体积下,它们要对应的价值
for(int j=m-v[u];j>=0;j--) //枚举体积 ,(m减当前物品的体积)留一个空位,从大到小(只能选一次) 若体积大于等于当前物品体积,需要在之前空出的位置,把这个物品加进去
f[u][i-v[u]]+w[u];更新的价值若体积小于等于当前物品体积,整个子树一个节点都不选择(依赖性)for(int k=0;k<=j;k++) //枚举物品组里面的每个物品 f[u][j]=max(f[u][j],f[u][j-k]+f[son][k]); //更新,看做一维 //每个节点都会有一个f[j],把f[u][j]看做01背包的f
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;const int N=110;
int n,m;
int h[N],e[N],ne[N],idx;
int v[N],w[N],f[N][N];void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{ //先把所有的子节点都算出来 for(int i=h[u];i!=-1;i=ne[i]){ //先枚举物品组 int son=e[i];dfs(son); //每个子节点都是一个物品组 //这里的物品必须要选择 ,依赖性 for(int j=m-v[u];j>=0;j--) //枚举体积 ,留一个空位,从大到小(只能选一次) for(int k=0;k<=j;k++) //枚举物品组里面的每个物品 f[u][j]=max(f[u][j],f[u][j-k]+f[son][k]); //更新,看做一维 //每个节点都会有一个f[j],把f[u][j]看做01背包的f }for(int i=m;i>=v[u];i--)f[u][i-v[u]]+w[u];for(int i=0;i<v[u];i++)f[u][i]=0;
}
int main(){memset(h,-1,sizeof h);cin>>n>>m;int root;for(int i=1;i<=n;i++){int p;cin>>v[i]>>w[i]>>p;if(p==-1)root=i;else add(p,i); }dfs(root);cout<<f[root][m]<<endl; //初始化的时候把所有体积都初始化为0,表示体积最多是m的情况下,最大价值为多少 return 0;
}
九大背包问题专题--有依赖的背包问题(树形Dp结合)相关推荐
- 九大背包问题专题--背包问题求具体方案数
8.背包问题求具体方案数 问题: 有N件物品和一个容量是V的背包. 每件物品只能用一次,第i件物品的体积是vi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包的容量,且价值总和最 ...
- 九大背包问题专题--分组背包问题
6.分组背包问题 问题: 有N组物品和一个容量是V的背包. 第组物品有若干个,同一组内的物品最多只能选一个每件物品的体积是vij,价值是wij.其中i是组号,j是组内编号. 求解将哪些物品装入背包,可 ...
- 九大背包问题专题--二维费用的背包问题
5.二维费用的背包问题 问题: 有N件物品和一个容量是V的背包,背包能承受的最大重量是M. 每件物品只能用一次,体积是vi,重量是mi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过 ...
- 九大背包问题专题--混合背包问题(状态转移)
4.混合背包问题 问题: 有N件物品和一个容量是V的背包. 物品一共有三类: 第一类:物品只能用1次(01背包) 第二类:物品可以用无限多次(完全背包) 第三类:物品最多只能用si次(多重背包) 每种 ...
- 九大背包问题专题--多重背包问题(二进制优化方法;单调队列问题)
3.多重背包问题1 题目: 有N件物品和一个容量是V的背包. 第i种物品最多有si件,每件的体积是vi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包的容量,且价值总和最大. 输 ...
- 各种背包详解(自己总结) 金明的预算和LOL(可依赖的背包问题)
在讲可依赖背包之前先回顾下背包九讲的内容,现在做dp多了发现背包问题真的是dp的鼻祖,好多种问题都是基于背包的模型发展而来,就是不是基于背包的,把背包搞懂也有利于你自己学习dp,以此来想到其它状态转移 ...
- Consumer HDU - 3449【dp-有依赖的背包问题】
题意简述: FJ打算去购物,在此之前,他需要一些盒子来装他要买的各种各样的东西.每个盒子都用来携带一些特定的东西(也就是说,如果他要买这些东西,他必须事先买到盒子).每种东西都有自己的价值.现在FJ的 ...
- 依赖的背包问题(c++)
该博客主要是对于Acwing上题解的一个解释与记录 贴上大佬的题解,感谢da AcWing 10. 有依赖的背包问题(思路不同于dxc,但是个人感觉更好理解) - AcWing 有 NN 个物品和一个 ...
- 有树形依赖的背包问题(附代码注释)
有 NN 个物品和一个容量是 VV 的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2 ...
最新文章
- Xamarin XAML语言教程基础语法篇大学霸
- ajax(Tibco) 与 SQL server 2005(5)
- UA MATH571A R语言回归分析实践 一元回归1 NBA球员的工资
- ARC107——C - Shuffle Permutation
- linux的文件搜索命令,Linux文件搜索命令find的用法 | 术与道的分享
- BigDecimal的异常记录:java.lang.ArithmeticException: Rounding necessary
- 李萍matlab实验报告,李萍, 张磊, 王垚廷. 基于Matlab的偏微分方程数值计算[J]. 齐鲁工业大学学报, 2017, 31(4): 39-43....
- pytorch一天速成第一部分——基础入门Tensor和cuda
- 程序员容易的疾病之干眼症(治疗篇)
- 爱普生AR眼镜应用场景图鉴:八个领域案例都在这里
- 前端HTML5面试题
- 矩阵理论——线性空间
- 一个与小球碰撞有关的有趣问题
- 前端下载excel文件功能的三种方法
- Unity Serialize总结
- 统计计算机软件应用作业,SPSS统计软件期末作业
- 火拼《俄罗斯方块》解析
- 为什么重写equals()就一定要重写hashCode()方法
- JumpServer 堡垒机 v2.25.0 发布
- 字符串入门练习题7 男孩或者女孩 题解
热门文章
- 一键编译安装LAMP环境
- 【python】爬虫入门:代理IP池的使用、文件的写入与网易云爬取时的注意事项
- ExtJS的History使用
- linux 查壳工具,die查壳工具 使用教程
- CentOs7 安装绿色版Nginx并配置开机启动
- 读《微波工程(第三版)》笔记 (10:终端接负载的无耗传输线)
- ArcEngine编辑模块——移动单个要素的实现方法
- vue + html2canvas + ArcGIS 3.x 地图一键截图功能踩坑之路(一)
- 查找算法的实现c语言,查找算法的实现(C语言版)
- 用python画星空的代码简单-【Python】手把手教你绘制星空旅游线路图