luogu P2015 二叉苹果树
这应该算一道树形背包吧,虽然我还是分不太清树形背包和树形dp的区别……
首先dp[i][u][j] 表示在u的前 i 棵子树中,留了 j 条树枝时最大的苹果数量,而且根据题目描述,这些留下的树枝一定都连在u上。
然后我们从1~j 枚举 k,于是
dp[i][u][j] = max(dp[i - 1][u][j], dp[i - 1][u][j - k] + dp[i - 1][v][k - 1] + cost[u->v])
思路就是我们让v所在的子树和u相连取更新答案。
j 的范围是枚举到当前的v时,u的子树中树枝的数量。
然后我们可以把第一维优化掉。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, q;
vector<int> v[maxn], c[maxn]; bool vis[maxn];
int edg[maxn], dp[maxn][maxn];
void dfs(int now)
{
vis[now] = ;
for(int i = ; i < (int)v[now].size(); ++i)
{
if(!vis[v[now][i]])
{
dfs(v[now][i]);
edg[now] += edg[v[now][i]] + ;
for(int j = edg[now]; j > ; --j)
for(int k = j; k > ; --k)
dp[now][j] = max(dp[now][j], dp[now][j - k] + dp[v[now][i]][k - ] + c[now][i]);
}
}
} int main()
{
n = read(); q = read();
for(int i = ; i < n; ++i)
{
int x = read(), y = read(), co = read();
v[x].push_back(y); c[x].push_back(co);
v[y].push_back(x); c[y].push_back(co);
}
dfs();
write(dp[][q]); enter;
return ;
}
luogu P2015 二叉苹果树的更多相关文章
- P2015 二叉苹果树
P2015 二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接 ...
- 洛谷 P2015 二叉苹果树 (树上背包)
洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...
- P2015 二叉苹果树,树形dp
P2015 二叉苹果树 题目大意:有一棵二叉树性质的苹果树,每一根树枝上都有着一些苹果,现在要去掉一些树枝,只留下q根树枝,要求保留最多的苹果数(去掉树枝后不一定是二叉树) 思路:一开始就很直接的想到 ...
- 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解
二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...
- 【Luogu】P2015二叉苹果树(DP,DFS)
题目链接 设f[i][j][k]表示给以i为根节点的子树分配j条可保留的树枝名额的时候,状态为k时能保留的最多苹果. k有三种情况. k=1:我只考虑子树的左叉,不考虑子树的右叉,此时子树能保留的最多 ...
- 洛谷P2015 二叉苹果树
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
- 洛谷—— P2015 二叉苹果树
https://www.luogu.org/problem/show?pid=2015 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点 ...
- 洛谷 P2015 二叉苹果树
老规矩,先放题面 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端 ...
- P2015 二叉苹果树 (树形动规)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
随机推荐
- Cheatsheet: 2018 05.01 ~ 07.31
JAVA Java Tips: Creating a Monitoring-Friendly ExecutorService Other Modeling the Card Game War in C ...
- HTML是什么与基础格式
html 又称 超文本标记语言. 网页的本质其实就是html代码,通过浏览器,将html转换翻译成用户可以看得懂的展现丰富的页面. 所以制作网站的本质,其实就是编写html代码. HTML基础格式 & ...
- Python随笔目录
Python 一.Python基础 Python入门 数据类型 函数(迭代器生成器三元表达式) 模块和常用内置模块 面向对象 网络编程(socket) 并发编程 ... 二.数据库 MySQL PyM ...
- JQuery漂浮广告代码
<!doctype html><html><head><meta charset="utf-8"><title>jque ...
- C++ 线程学习
原文:http://blog.csdn.net/wzy_1988/article/details/46562921 线程的概念 C++中的线程的Text Segment和Data Segment都是共 ...
- maven项目在idea下右键不出现maven的解决办法
重新删除项目,导出 再重新引入.
- 算法之求质数(Java语言)
质数(Prime number) 又称素数,指在的自然数中,除了1和该数自身外,无法被其他自然数整除的数(也可定义为只有1与该数本身两个因数的数). 算法原理 验证一个数字 n 是否为素数的一种简单但 ...
- 2.java相对路径与绝对路径
1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:xyz/test.txt 代表了test.txt文件的绝对路径.http://www. ...
- SqlServer数据库(可疑)的解决办法
当数据库发生这种操作故障时,可以按如下操作步骤可解决此方法, 打开数据库里的Sql 查询编辑器窗口,运行以下的命令. // 1.使用指定值强制重新配置:(1.0表示为真假) sp_configure ...
- asp.net生成PDF文件参考 .
TextSharp 是用来生成 PDF 的一个组件,在 1998 年夏天的时候,Bruno Lowagie ,iText 的创作者,参与了学校的一个项目,当时使用 HTML 来生成报告,但是,使用 ...