有依赖的背包 首先依赖的概念,就是一个东西依附与一个东西之上,我们想买附品的话必须要把主品先买下来,这个可以先做下这道题 https://www.cnblogs.com/Lis-/p/11047466.html 上面就讲到了主件和附件的概念,要想买附件就必须先买其主件 上面这个题最多只有两个附件,情况不多,所以可以直接枚举,现在依赖背包即是上面这个题改成是附件数量不限 每个分组策略数就太多了,主件+1附件 / 主件+2附件 / 主件+3附件  /  主件+4附件...... 分组有个性质 他只能…
Outing Input Output Sample Input 4 4 1 2 3 4 Sample Output 4 分组背包: for 所有的组k for v=V..0 for 所有的i属于组k f[v]=max{f[v],f[v-c[i]]+w[i]} 有一辆能载客m的车,有n个人,然后第i个人上车的条件是第a[i]个人要上车,问最多能上几个. 显然,一个连通块至多含有一个环.每一块的价值范围在[环点,块点]之间,将每一块视为一组,从每组的范围中任取一值,组成不超过m的最大值.因此可转换…
题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; const int N=105; const…
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> using namespace std; ; int dp[maxn][maxn]; //dp[i][j]表示以i为根,保留j个点的最大权值. int N,Q; int G[maxn][maxn]; int num[maxn]; //以i为根的树的节点个数. //这里…
题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m)时选最多的宝物,而一个子节点中只可以选择一个状态进行转移,每个节点有若干个子节点,问题就转换为分组背包,几个子节点就是几个分组背包,体积是选几个地点,价值是宝物价值. 状态转移方程: dp[v][1] = Money[v]; (v为叶子节点)                    dp[v][j] = m…
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 3397    Accepted Submission(s): 1588 Problem Description Humans have discovered a kind of new metal mineral on Mars which are d…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最优值,那么dp[i][j]=max(dp[i][j],dp[son][k]+dp[i][j-k]) 其中son为i的儿子 然后从叶子节点往上进行背包即可 刚接触的同学会有疑问:就是不知道怎样将题目中的数据建为一个树,其实很简单,只要把0作为根结点即可 0节点的value初始化为0 然后dp[0][m…
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 输入输出格式 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=100). N表示树的结点数,Q表示要保留的树枝数量.接下来N-1行描述树枝的信息. 每行3个整数,前两个是它连接的结点的编号.第3个数是…
题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/1]表示在子树u中走j步的最大价值(回到u/不回到u).显然dp[u][j][1]>=dp[u][j][0],所以dp[1][m][1]就是最终答案. 假设v为u的子结点,k为到v且在v中所用步数,那么转移方程分3步,为: dp[u][j][0]=max(dp[u][j][0] , dp[u][j-…
题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 Sample Output 3 2 转移方程: dp[i][j]=min(dp[i][j],dp[i][j*k],dp[son[i]][k]+len(i,son[i])*k) 方程还是比较好写的,主要是要遍历所有的点 下面我们分析一下第一个样例 1 / \ / \ 2 3 我们派了一个机器人去3,…
题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的总代价.则状态转移方程为: dp(root,k)=min(dp(root,k),dp(son,j)+dp(root,k-j)+j*w(root,son))  j>0 要注意,当j为0的时候表示遍历完son这个子树后所有的机器人都回到root.可以证明,如果让遍历son的所有的机器人都回到root,那…
题目大意:将一棵n个节点的有根树,删掉一些边变成恰有m个节点的新树.求最少需要去掉几条边. 题目分析:定义状态dp(root,k)表示在以root为根节点的子树中,删掉一些边变成恰有k个节点的新树需要删去的最少边数.对于根节点root的某个儿子son,要么将son及其所有的子节点全部删掉,则dp(root,k)=dp(root,k)+1,只需删除root与son之间的边:要么在son的子树中选出一些边删掉,构造出有j个节点的子树,状态转移方程为dp(root,k)=max(dp(root,k),…
题目大意:给一棵带边权的有根树,每个叶子节点有权.边权表示代价,叶子节点的权值代表可以补偿多少代价.问从根节点最多可以到达多少个叶子,使得付出的总代价不大于0. 题目分析:定义状态dp(u,k)表示从u开始到达k个叶子所花费的最小代价.则状态转移方程为: dp(u,k)=min(dp(u,k),dp(son,j)+dp(u,k-j)+u到son的代价). ps:要加上优化,否则超时. 代码如下: # include<iostream> # include<cstdio> # inc…
题目大意:给出一片森林,总共有n个点,并且都有权值.从中选出m个,使权值和最大.其中,选某个节点之前必须先选其父节点. 题目分析:给所有的树都加一个共同的权值为0的根节点,使森林变成一棵树.定义状态dp(u,k)表示在以节点u为根节点的组中选k个节点的最大权值.则状态转移方程为: dp(u,k)=max(dp(u,k),dp(v,j)+dp(u,k-j),其中v是u的子节点. 代码如下: # include<iostream> # include<cstdio> # include…
题目链接:https://vjudge.net/problem/HDU-4276 题意:给出一棵树,起点为1,时间为V,终点为n,每个点有一个价值a[u],每条边有一个时间花费w,求在时间V内到达终点n可以获得的最大价值. 思路: 考虑边有两种情况,一种是属于1->n路径上的(只用走一次),一种是不属于该路径上的(需要走两次),为了统一,不妨把V减去1-n路径上的权值和,然后把1->n路径上边的权值置为0. 此时就转换为求在起点1,在时间V内回到起点的最大价值.用dp[u][j]表示在点u有时…
题目链接:https://vjudge.net/problem/HDU-4003 题意:给一棵边权树,在树根s有m个人,要通过m个人遍历到所有点,一个人经过一条边花费为边的权值,求最小花费(可以走已经走过的边). 思路: 状态比较好想,用dp[u][j]表示在u结点的子树中有j个人的最小花费.但转移方程有点难想. 重要的是怎么处理dp[u][0],对dp[v][0],即在v结点的子树中有0个人的最小花费,那么只能通过v的父结点u过来机器人,假设来x个人,那这x个人在遍历v子树所有点之后还要回到u…
codevs 1378 选课 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得相应的学分. 在选修课程中,有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才能选修.例如<Frontpage>…
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得相应的学分. 在选修课程中,有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才能选修.例如<Frontpage>必须在选修了<Windows操作基础>之后才能选修.我们称<Windows操作基础>是<Fro…
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡.你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?  Input每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡…
CH 5402 选课 \(solution:\) 很有讨论套路的一道题,利用树的结构来表示出不同课程之间的包含关系(这里还要建一个虚点将森林变成一颗打大树).然后用子树这个概念巧妙的消除了因为这些包含关系而使DP产生的后效性.我们在某一棵子树上完全背包使就不必去管之前的必要课程,然后以每一个节点都来一次分组背包也满足有局部的最优解扩散到整体上去. \(code:\) #include<iostream> #include<cstdio> #include<iomanip>…
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多. 输入输出格式 输…
https://www.luogu.org/problemnew/show/P2014 树形背包的裸题..当版子好了. $f[i][j][k]$表示子树$i$选前$j$个孩子,共$k$个后代节点时的最大价值.然后$j$那一维是可以滚动的(但同时也要注意枚举变成了倒序),所以可以去掉. $f[i][j]$表示子树$i$共选$k$个后代节点时的最大价值. 然后每个点可以抽象为一个背包,他的每个孩子包含一组物品,一组物品中包括以孩子为子树,选v个其后代节点形成的最大价的共v+1个物品(1指的是只有孩子…
(上不了p站我要死了,侵权度娘背锅) Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j).幸运的是,一个软件最多依赖另外一个软件.如果一个软件不能正常工作,那么它能够发挥的作用为0. 我们现在知道了软件之…
BZOJ 题目的限制即:给定一棵树,只能任选一个连通块然后做背包,且每个点上的物品至少取一个.求花费为\(m\)时最大价值. 令\(f[i][j]\)表示在点\(i\),已用体积为\(j\)的最大价值. 如果物品数量为\(1\),那就是一个树形依赖背包(选儿子必须选父亲),用DFS序优化转移:\(f[i][j]=\max(f[i+1][j-v_i]+w_i,\ f[i+sz_i][j])\)(选该节点就可以从上一个点,即子树内转移,否则只能从另一棵子树转移),复杂度\(O(nm)\). 物品数量…
BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明.与\(shadowice\)的做法还是有差异的(比如并没有明显用到后序遍历的性质),而且用这种写法可能跑的比较轻松? (另外你只要想明白\(f,h\)是代表啥,就很好理解了...) 问题等价于树形依赖背包,允许一条链每个点各免费取一次. 免费取一条链即\(t\leq h+k\)的限制.这样最优解一定会免费取了一条从叶子到根节点的链. 现在考虑一下怎么做.…
菜菜推荐的“水题”虐了我一天T T...(菜菜好强强qwq~ 显然是个分数规划题,二分答案算出p[i]-mid*s[i]之后在树上跑依赖背包,选k个最大值如果>0说明还有更优解. 第一次接触树形依赖背包,所以之前写的十几发WA和TLE都是错误写法,我还是naive啊T T 树形依赖背包的普遍做法是按dfs序DP,设f[i][j]为dfs序为i的点,已经选了j个点的最大价值,nxt[i]为i的下一个子树的dfs序则有: f[nxt[i]][j]=f[i][j] f[i+1][j+1]=f[i][j…
参考论文http://wenku.baidu.com/view/8ab3daef5ef7ba0d4a733b25.html 参考一篇写的很好的博文http://www.cnblogs.com/GXZC/archive/2013/01/13/2858649.html 题目链接http://www.luogu.org/problem/show?pid=1273 首先确定泛化物品的定义:价值随着体积变化的物体,如01背包中的f[i](体积为i时的最大价值最f[i]). 泛化物品+普通物品: 还是01背…
题目链接 问题:有n个人,最多选k个,如果选了某个人就必须选他指定的另一个人,问最多能选多少个人. 将每个人所指定的人向他连一条单向边,则每一个点都有唯一的前驱,形成的图是个基环树森林,在同一个强连通分量里的点要么全选,要么全不选. 首先用Tarjan算法将每个强连通分量(基环树上的环)缩成一个点,这样每棵基环树就变成了普通的树了. 定义每颗树上没有入度的点为树根,建立一个虚根与每棵树的根连一条边,将森林转化成树,对根节点求一遍树形背包即可. 树形依赖背包是树形背包的一个特例,即树形背包在根节点…
题意 题目链接 Sol 树形依赖背包板子题 树形依赖背包大概就是说:对于一个点,只有选了它的父亲才能选自身 把dfs序建出来,倒过来考虑 设\(f[i][j]\)表示从第\(i\)个节点往后背包体积为\(j\)的最大价值 转移的时候,只有选了该点才能从子树中转移而来 \(f[i][j] = max(f[i + 1][j - w[i]] + val[i], f[i + siz[rev[i]]][j]);\) #include<bits/stdc++.h> using namespace std;…
和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物. 距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离, 那么就可以回答走x距离能访问到的最大结点数量. 当访问了一棵子树,想要访问子树外的结点时,一定要先从子树的根结点出来. 状态可以定义为dp[u][k][?],u表示根节点,k表示访问u的k个子结点,?的取值为0和1表示 不回到u 和 回到u. 不难想到转移过程: dp[u][k][0] <- dp[u][a][1…