依赖的背包问题(c++)
该博客主要是对于Acwing上题解的一个解释与记录
贴上大佬的题解,感谢da
AcWing 10. 有依赖的背包问题(思路不同于dxc,但是个人感觉更好理解) - AcWing
有 NN 个物品和一个容量是 VV 的背包。
物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
如下图所示:
如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。
每件物品的编号是 ii,体积是 vivi,价值是 wiwi,依赖的父节点编号是 pipi。物品的下标范围是 1…N1…N。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行有两个整数 N,VN,V,用空格隔开,分别表示物品个数和背包容量。
接下来有 NN 行数据,每行数据表示一个物品。
第 ii 行有三个整数 vi,wi,pivi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果 pi=−1pi=−1,表示根节点。 数据保证所有物品构成一棵树。
输出格式
输出一个整数,表示最大价值。
数据范围
1≤N,V≤1001≤N,V≤100
1≤vi,wi≤1001≤vi,wi≤100
父节点编号范围:
- 内部结点:1≤pi≤N1≤pi≤N;
- 根节点 pi=−1pi=−1;
输入样例
5 7
2 3 -1
2 2 1
3 5 1
4 7 2
3 6 2
输出样例:
11
首先分析一下变量和状态
这次我们的所有状态的集合是以x作为根结点的以j为背包的上限容量的集合。其中存的值的大小代表着最大价值。
翻译一下就是DP[x][j]是以x作为根结点,j为最大容量的放物品的最大价值。所以我们最后算出来的结果就在DP[root][volumn]当中
在每一个状态被处理的时候,我们将其看作分组的背包问题,但是这个分组指的是每个子树,是每个子树的最大容积,换句话说就是DP[x][j]=max(DP[x][j],DP[x][j-k]+DP[y][k])//y是x的子树之一的根结点也就是x的孩子结点之一,将k的容积划分给孩子结点来用的最大价值+j-k的容积给自己(该根结点本根)来用的和之前存下来的该组的划分不同的k容积大小给子树的结果相比较最后取最大的情况作为给以x为根结点的j为最大容积的最大价值。
也就是说k是一个互斥的情况,是分组背包问题中,组内的物品,每组只能选一个或者不选。
将该结点的所有子树都尝试使用过了之后,就返回上一层,给上一层的根结点来使用。
而树形结构的创建也是一直让我很头疼的问题,yxc大佬的邻接表又很难懂,我准备用链表来做但是又感觉这种输入给的是各自的前驱的记录感觉很难搞,最后看到了大佬的解法。
vector<int> g[110];//建立
而在记录自己的父亲结点是谁的时候只要这样的操作就可以把自己悬挂在父结点下面了
for(i=1;i为结点序号,i小于等于总结点数量;i++)
{cin>>fa;g[fa]=i;
}
这样的话遍历自己的所有孩子也方便起来了。
而有些控制在大佬的代码里面也都有了,直接上大佬的代码
转载出处AcWing 10. 有依赖的背包问题(思路不同于dxc,但是个人感觉更好理解) - AcWing
#include<iostream>
#include<vector>
using namespace std;
int f[110][110];//f[x][v]表达选择以x为子树的物品,在容量不超过v时所获得的最大价值
vector<int> g[110];
int v[110],w[110];
int n,m,root;int dfs(int x)
{for(int i=v[x];i<=m;i++) f[x][i]=w[x];//点x必须选,所以初始化f[x][v[x] ~ m]= w[x]for(int i=0;i<g[x].size();i++){int y=g[x][i];dfs(y);for(int j=m;j>=v[x];j--)//j的范围为v[x]~m, 小于v[x]无法选择以x为子树的物品{for(int k=0;k<=j-v[x];k++)//分给子树y的空间不能大于j-v[x],不然都无法选根物品x{f[x][j]=max(f[x][j],f[x][j-k]+f[y][k]);}}}
}int main()
{cin>>n>>m;for(int i=1;i<=n;i++){int fa;cin>>v[i]>>w[i]>>fa;if(fa==-1)root=i;elseg[fa].push_back(i);}dfs(root);cout<<f[root][m];return 0;
}
依赖的背包问题(c++)相关推荐
- 九大背包问题专题--有依赖的背包问题(树形Dp结合)
9.有依赖的背包问题 问题: 有N件物品和一个容量是V的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如图所示 如果选择物品5,则必须选择物品1和 ...
- Consumer HDU - 3449【dp-有依赖的背包问题】
题意简述: FJ打算去购物,在此之前,他需要一些盒子来装他要买的各种各样的东西.每个盒子都用来携带一些特定的东西(也就是说,如果他要买这些东西,他必须事先买到盒子).每种东西都有自己的价值.现在FJ的 ...
- 各种背包详解(自己总结) 金明的预算和LOL(可依赖的背包问题)
在讲可依赖背包之前先回顾下背包九讲的内容,现在做dp多了发现背包问题真的是dp的鼻祖,好多种问题都是基于背包的模型发展而来,就是不是基于背包的,把背包搞懂也有利于你自己学习dp,以此来想到其它状态转移 ...
- 有树形依赖的背包问题(附代码注释)
有 NN 个物品和一个容量是 VV 的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2 ...
- hdu3449 有依赖的背包问题
题意: 给你一些物品,每个物品有自己的价值和花费,每个物品都对应一个箱子,每个箱子有价钱,买这个物品必须买相应的箱子,给你一个价钱,问最多可以获得多少价值 <提示:多个物品可能同时对 ...
- AcWing 10. 有依赖的背包问题
有 N 个物品和一个容量是 V 的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2是5 ...
- 有依赖的背包问题--java
有 NN 个物品和一个容量是 VV 的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2 ...
- Acwing--有依赖的背包问题
有 NN 个物品和一个容量是 VV 的背包. 物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点. 如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2 ...
- 背包模型------------有依赖的背包问题
有 NN 个物品和一个容量是 VV 的背包.物品之间具有依赖关系,且依赖关系组成一棵树的形状.如果选择一个物品,则必须选择它的父节点.如下图所示: 如果选择物品5,则必须选择物品1和2.这是因为2是5 ...
最新文章
- 机器学习中的数学基础(4.1):支持向量机Support Vector Machine(SVM)
- ModelCheckpoint 讲解【TensorFlow2入门手册】
- linux下influxdb安装教程,Linux下安装使用InfluxDB
- Java Minor发布计划再次进行了调整
- 把 mysql 整个加载进内存磁盘中_MySQL 缓冲池 是什么?
- Python绘制带标记和箭头的树结构
- nginx服务+LEMP搭建
- ICLR'22 | cosFormer:重新思考注意力机制中的Softmax
- verilog中generate用法及参数传递(转)
- boot客户管理系统源码_开源 SpringBoot+vueJs 前后端管理系统模版
- Linux环境下安装yafu
- 设计模式之模板方法模式
- 正则判断手机号地区_国内外手机号码正则表达式汇总
- Spring+SpringMVC+MongoDB案例
- table 表格边框线去重
- windows 启动修复总结
- 【工具篇】maven指令大全
- CSS设置背景颜色为透明
- [JZOJ5454]仔细的检查
- 软件开发中,站立会议的必要性