Description

给出一个 N 个节点的有根树,点编号 1 ∼ N ,编号为 i 的点有权值 v i 。请选出一个包含树根的,点数 不超过 K 的连通块,使得点权和最大。

Input

输入的第一行有二个整数 N , K ( K ≤ N ≤ 3000) 。 
接下来一行 N 个整数,第 i 个数描述编号为 i 的点的父亲编号,若该数为 0 ,则表示点 i 为树根。 
接下来一行 N 个整数,第 i 个数描述编号为 i 的点的权值。

Output

输出一行一个整数,描述最大的点权和。保证答案不会超过 231−1231−1。

题解:
这个题目我还是建议先自行百度树形背包,不然听不懂我在说什么!(不过估计看懂后就不会听我讲了QAQ),好了,这是道树形背包的裸题,状态是显然的,dp[i][j]表示dp到i号节点可以放j个节点的最大点权和,保障连通也很简单,只要让他强制选当前i号节点就可以,接下了的问题就是转移了,显然我们可以把每棵子树单词一个不定代价和价值的背包,那么我们先把当前节点也当成一个同样的背包,然后每次将一个子树与当前的根节点的不定背包合并,然后枚举下一棵子树,没听懂没关系,代码很清楚。
 
代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
const int MAXN=;
using namespace std;
struct edge{
int first;
int next;
int to;
}a[MAXN*];
int n,m,num=,roof;
int dp[MAXN][MAXN];
int W[MAXN]; void cl(){
memset(dp,,sizeof(dp));
} void addedge(int from,int to){
a[++num].to=to;
a[num].next=a[from].first;
a[from].first=num;
} void dfs(int now,int fa,int w){
if(w==) return;
for(int i=a[now].first;i;i=a[i].next){
int to=a[i].to;
if(to==fa) continue;
for(int j=;j<=w;j++) dp[to][j]=dp[now][j];
dfs(to,now,w-);
for(int j=;j<=w;j++) dp[now][j]=max(dp[now][j],dp[to][j-]+W[to]);
}
} int main(){
cl();
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
int x;
scanf("%d",&x);
if(x==) roof=i;
else addedge(i,x),addedge(x,i);
}
for(int i=;i<=n;i++) scanf("%d",&W[i]);
dfs(roof,,m);
printf("%d",dp[roof][m-]+W[roof]);
}
 

【DP合集】tree-knapsack的更多相关文章

  1. dp合集 广场铺砖问题&&硬木地板

    dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...

  2. 9.15 DP合集水表

    9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...

  3. 9.14 DP合集水表

    9.14 DP合集水表 关键子工程 在大型工程的施工前,我们把整个工程划分为若干个子工程,并把这些子工程编号为 1. 2. --. N:这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某 ...

  4. 【CJOJ2498】【DP合集】最长上升子序列 LIS

    题面 Description 给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的n个整数组成的序列 ...

  5. CJOJ 【DP合集】最长上升序列2 — LIS2

    题面 已知一个 1 ∼ N 的排列的最长上升子序列长度为 K ,求合法的排列个数. 好题(除了我想不出来我应该找不到缺点), 想一想最长上升子序列的二分做法, 接在序列后面或者替换. 所以对于每一个位 ...

  6. 【DP合集】m-knapsack

    给出 n 个物品,第 i 个物品有重量 w i .现在有 m 个背包,第 i 个背包的限重为 c i ,求最少用几个背 包能装下所有的物品. Input 输入的第一行两个整数 n, m ( n ≤ 2 ...

  7. 【DP合集】背包 bound

    N 种物品,第 i 种物品有 s i 个,单个重量为 w i ,单个价值为 v i .现有一个限重为 W 的背包,求能容 纳的物品的最大总价值. Input 输入第一行二个整数 N , W ( N ≤ ...

  8. 【DP合集】合并 union

    给出一个 1 ∼ N 的序列 A ( A 1 , A 2 , ..., A N ) .你每次可以将两个相邻的元素合并,合并后的元素权值即为 这两个元素的权值之和.求将 A 变为一个非降序列,最少需要多 ...

  9. 【DP合集】棋盘 chess

    给出一张 n × n 的棋盘,格子有黑有白.现在要在棋盘上放棋子,要求: • 黑格子上不能有棋子 • 每行每列至多只有一枚棋子 你的任务是求出有多少种合法的摆放方案.答案模 109+7109+7 . ...

随机推荐

  1. 【LeetCode】435-无重叠区间

    题目描述 给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠. 注意: 可以认为区间的终点总是大于它的起点. 区间 [1,2] 和 [2,3] 的边界相互"接触", ...

  2. Dijkstra算法的Java实现

    package main.java; import main.java.utils.GraphUtil; import java.util.ArrayDeque; import java.util.L ...

  3. Redis字符串键的底层原理

    before C语言基础 Redis基础 导入 redis的命令如下: set x "hello"; get x; hello Redis作为一种存储字符串的缓存结构,其具体实现是 ...

  4. Redis集群的离线安装以及原理理解

    一.本文主要是记录一下Redis集群在linux系统下离线的安装步骤,毕竟在生产环境下一般都是无法联网的,Redis的集群的Ruby环境安装过程还是很麻烦的,涉及到很多的依赖的安装,所以写了一个文章来 ...

  5. SpringCloud(三)Ribbon与Feign

    上一篇使用了Eureka与Ribbon组件做了最简单的的服务注册与发现,我们知道Eureka是实现服务治理中心的组件,但是上一篇Eureka没有实现集群,这样没有保证到Eureka Server的高可 ...

  6. 在VMware中就显示lo回环IP:127.0.0.1的解决办法。

    在VMware时由于某些原因导致,在使用ifconfig只会显示lo,不显示其他的东西 步骤:1.sudo lshw -numeric -class network 2.sudo route -nv ...

  7. 泛型接口、JAVA API、包装类

    泛型接口就是拥有一个或多个类型参数的接口 语法: public interface 接口名<类型形参>{ 方法名(类型形参 类型形参实例); } 示例: public interface ...

  8. Java 教程 (Java 对象和类)

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例(对象不是找个女朋友 ...

  9. 进击的.NET 在云原生时代的蜕变

    你一定看过这篇文章 <进击的 Java ,云原生时代的蜕变>,  本篇文章的灵感来自于这篇文章.明天就将正式发布.NET Core 3.0, 所以写下这篇文章让大家全面认识.NET Cor ...

  10. 32 (OC)* keyChain的本质

    1:它是一个sqlite数据库,其保存的所有数据都是加密过的. 2:Keychain是加密规则(key)的集合.每个规则必须含有以下三个要素:认证算法.认证密钥(加密字符串).规则的时间. 3:key ...