P2015 二叉苹果树,树形dp
P2015 二叉苹果树
题目大意:有一棵二叉树性质的苹果树,每一根树枝上都有着一些苹果,现在要去掉一些树枝,只留下q根树枝,要求保留最多的苹果数(去掉树枝后不一定是二叉树)
思路:一开始就很直接的想到树形dp上了,因为就是每个树枝要与不要的问题,但要找到如何找到一个转移方程呢,首先我们想一下,最后保留的是一棵树,所以肯定是从根节点开始,然后在它的两个子节点中向下延伸不停的选择保留树枝,换句话说,假如需要保留q根树枝,我们已经知道了根节点的两个子节点保留任意根数的最多苹果数,那么根节点要保留q根树枝的状态,就是遍历一下其中一个根节点保留i根树枝,然后另一个根节点保留q-i根树枝,不停更新答案,转换成转移方程便是:
dp[u][q]=max(dp[u][q],dp[v1][i]+dp[v2][q-i]) (dp[i][j]就代表i节点保留j根树枝的最大苹果数)
不过需要考虑到的是,根节点没有入度,但其他节点有入度,以及当前节点在它的子树的树枝数,也就是:
dp[u][q]=max(dp[u][q],dp[v1][i]+dp[v2][q-i-g]+c) (g就是它的入度,根节点是0,其他都是1,而c就是父节点和它连接的那根树枝的苹果数)
#include<cstdio>
#include<cstring>
const int N=;
struct Side{
int to,ne,val;
}S[*N];//前向星存边
int sn,head[N],dp[N][N]={};
int max(int a,int b){
return a>b ? a : b;
}
void add(int u,int v,int c)
{
S[sn].to=v;
S[sn].val=c;
S[sn].ne=head[u];
head[u]=sn++;
}
int treed(int u,int f,int c,int g)//当前节点,父节点,父节点与它相连树枝上的苹果数
{
int v[]={},du[]={},s=;//分别保留两个编号以及总树枝数
for(int i=head[u];i!=-;i=S[i].ne)
{
if(S[i].to!=f)
{
v[s]=S[i].to;
du[s]=treed(v[s],u,S[i].val,);
s++;
}
}
for(int i=;i<=du[]+du[]+g;i++)//du[0]+du[1]+g就是这个节点为根节点最多能保留的树枝数
{
for(int j=max(,i-du[]-g);j<=du[]&&j<=i-g;j++)
dp[u][i]=max(dp[u][i],dp[v[]][j]+dp[v[]][i-j-g]+c);
}
return du[]+du[]+g;
}
int main()
{
int n,q,u,v,c;
memset(head,-,sizeof(head));
scanf("%d%d",&n,&q);
for(int i=;i<n;i++)
{
scanf("%d%d%d",&u,&v,&c);
add(u,v,c);//没有严格给出方向,建双向边
add(v,u,c);
}
treed(,,,);
printf("%d\n",dp[][q]);
return ;
}
代码千万条,自觉第一条,复制粘贴爽,打铁泪两行
P2015 二叉苹果树,树形dp的更多相关文章
- P2015 二叉苹果树[树形dp+背包]
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 【P2015】二叉苹果树 (树形DP分组背包)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...
- P2015 二叉苹果树 (树形动规)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 二叉苹果树——树形Dp(由根到左右子树的转移)
题意:给出一个二叉树,每条边上有一定的边权,并且剪掉一些树枝,求留下 Q 条树枝的最大边权和. ( 节点数 n ≤100,留下的枝条树 Q ≤ n ,所有边权和 ∑w[i] ≤30000 ) 细节:对 ...
- 【Luogu】P2015二叉苹果树(DP,DFS)
题目链接 设f[i][j][k]表示给以i为根节点的子树分配j条可保留的树枝名额的时候,状态为k时能保留的最多苹果. k有三种情况. k=1:我只考虑子树的左叉,不考虑子树的右叉,此时子树能保留的最多 ...
- 洛谷 P2015 二叉苹果树 (树上背包)
洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...
- P2015 二叉苹果树
P2015 二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接 ...
- 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解
二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...
- 洛谷 P2015 二叉苹果树(codevs5565) 树形dp入门
dp这一方面的题我都不是很会,所以来练(xue)习(xi),大概把这题弄懂了. 树形dp就是在原本线性上dp改成了在 '树' 这个数据结构上dp. 一般来说,树形dp利用dfs在回溯时进行更新,使用儿 ...
随机推荐
- Python 3.8.0 正式版发布,新特性初体验 全面介绍
Python 3.8.0 正式版发布,新特性初体验 北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性. 赋值表达式 PE ...
- sysbench测试
什么是基准测试 数据库的基准测试是对数据库的性能指标进行定量的.可复现的.可对比的测试. 基准测试与压力测试 基准测试可以理解为针对系统的一种压力测试.但基准测试不关心业务逻辑,更加简单.直接.易于测 ...
- MySQL mysql-5.7.21-winx64.zip安装指南
一.下载mysql-5.7.21-winx64.zip压缩包 二.解压 1.在目录mysql-5.7.21-winx64下新建data文件夹 !!!如果已经存在data文件夹,请删除其中ib_logf ...
- 将磁盘从FAT格式转换为NTFS格式的方法
不需要进行格式化,只需在命令提示符中输入如下内容:CONVERT X:/FS:NTFS把X换成你需要的盘符,转一个盘需十几或几十秒不等..注意:此方法不可逆转,FAT32转到NTFS后不可转回,当然也 ...
- 添加Entity Framework Core,数据库迁移
1.建立Entity 建立IEntity的接口 建立实现IEntity接口的抽象类Entity 建立类继承抽象类Entity 2. 数据库放到infrastructure的项目中 3.注册和配置这个d ...
- 【原创】大叔经验分享(64)cloudera manager agent启动组件进程过程
概述 The Agent is started by init.d at start-up. It, in turn, contacts the Cloudera Manager Server and ...
- 服务端相关知识学习(五)之Zookeeper leader选举
在上一篇文章中我们大致浏览了zookeeper的启动过程,并且提到在Zookeeper的启动过程中leader选举是非常重要而且最复杂的一个环节.那么什么是leader选举呢?zookeeper为什么 ...
- 如何从git上批量拉取本地当前分支的所有代码
1 我本地有一个文件_netrc文件里面存储这git的相关信息,包括用户名和密码 你可以根据自己的git相关信息配置自己的信息 2 我当前的分支是dev,我要拉取当前分支下的所有代码,编写shell脚 ...
- another-redis-desktop-manager
brew cask install another-redis-desktop-manager
- WLW模板插件Text Templat的应用举例
WLW的模板插件:WLWTextTemplates 安装之后,如下图所示: 点击这个按键之后,出现下图: 按上图提示点击"Add new Template",出现下图: 举个例 ...