洛谷2015(树形dp)
要点
- 是树形的考虑dfs
- 分为取一枝,取两枝两种情况,将它们的合法情况进行暴举取最好答案即可,貌似我乱搞得相当冗……
- 顺手记忆化
- 正解应该是树上背包
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <functional>
#include <vector>
#define pb push_back
using namespace std;
int N, Q, cost[101][101], size[101], dp[101][101];
vector<int> adj[101];
int dfs(int cur, int fa, int rest) {
	if (rest <= 0)	return 0;
	if (dp[cur][rest] >= 0)	return dp[cur][rest];
	int res = 0;
	vector<int> v;
	for (int son : adj[cur]) {
		if (son == fa)	continue;
		if (size[son] + 1 >= rest)	res = max(res, dfs(son, cur, rest - 1) + cost[cur][son]);
		v.pb(son);
	}
	if (v.size() == 2 && rest >= 2) {
		int r = rest - 2;
		for (int i = 0; i <= min(r, size[v[0]]); i++)
			if (r - i <= size[v[1]]) {
				res = max(res, dfs(v[0], cur, i) + dfs(v[1], cur, r - i) + cost[cur][v[0]] + cost[cur][v[1]]);
			}
	}
	return dp[cur][rest] = res;
}
int main() {
	scanf("%d %d", &N, &Q);
	if (Q == N)	Q--;
	for (int i = 1; i < N; i++) {
		int u, v, c;
		scanf("%d %d %d", &u, &v, &c);
		cost[u][v] = cost[v][u] = c;
		adj[u].pb(v), adj[v].pb(u);
	}
	function<void(int, int)> S = [&](int cur, int fa) {
		size[cur] = 0;
		for (int son : adj[cur])
			if (son != fa) {
				S(son, cur);
				size[cur] += size[son] + 1;
			}
	};
	S(1, 0);
	memset(dp, -1, sizeof dp);
	printf("%d\n", dfs(1, 0, Q));
	return 0;
}
树上背包版,j-k要使用上个儿子的所以j倒序:
#include <cstdio>
#include <algorithm>
#include <vector>
#define pb push_back
using namespace std;
int N, Q, cost[101][101], dp[101][101];
vector<int> adj[101];
int dfs(int cur, int fa) {
	int ret = 0;
	for (int son : adj[cur]) {
		if (son == fa)	continue;
		int size = dfs(son, cur);
		ret += size + 1;
		for (int j = min(Q, ret); j; j--) {
			for (int k = 1; k <= min(j, size + 1); k++) {
				dp[cur][j] = max(dp[cur][j], dp[cur][j - k] + dp[son][k - 1] + cost[cur][son]);
			}
		}
	}
	return ret;
}
int main() {
	scanf("%d %d", &N, &Q);
	if (Q == N)	Q--;
	for (int i = 1; i < N; i++) {
		int u, v, c;
		scanf("%d %d %d", &u, &v, &c);
		cost[u][v] = cost[v][u] = c;
		adj[u].pb(v), adj[v].pb(u);
	}
	dfs(1, 0);
	printf("%d\n", dp[1][Q]);
	return 0;
}
洛谷2015(树形dp)的更多相关文章
- 洛谷教主花园dp
		洛谷-教主的花园-动态规划 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价 ... 
- 洛谷 p6858 深海少女与胖头鱼 洛谷月赛 期望dp
		洛谷10月月赛 2 t2 深海少女与胖头鱼 题目链接 参考资料:洛谷10月赛2讲评ppt; 本篇题解考完那天就开始写,断断续续写到今天才写完 本题作为基础的期望dp题,用来学习期望dp还是很不错的 ( ... 
- 洛谷P4719 动态dp
		动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ... 
- 2018普及组摆渡车洛谷5017(dp做法)
		啦啦啦,这一篇是接上一篇的博客,上一篇是记忆化搜索,而这一篇是dp+前缀和小技巧 dp这种玄学做法我这种蒟蒻当然不是自己想出来的,参考https://blog.csdn.net/kkkksc03/ar ... 
- 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]
		题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ... 
- 洛谷1373(dp)
		常规线性dp,需要时就加一维.\(dp[i][j][t][s]\)表示在点\((i,j)\)时瓶子里剩\(t\)且为\(s\)走(0代表小a,1代表uim)时的方案数. de了半天发现是初次尝试的快速 ... 
- 洛谷P4719 动态DP —— 动态DP(树剖+矩乘)
		题目:https://www.luogu.org/problemnew/show/P4719 感觉这篇博客写得挺好:https://blog.csdn.net/litble/article/detai ... 
- 洛谷1280(dp)
		题目性质:1.当前节点空闲则必须做任务,而不是可选可不选:2.然而前面的如果能覆盖当前节点,就可以不选. 解决方法:倒着扫可以很好地解决这两个问题.dp[i]为时刻i可得的最大空闲时间.如果此刻没有任 ... 
- 洛谷1941(dp)
		常规的dp,当前有值且碰不到管子就转移,可以连跳的操作我就加了一维表示当前是不是连跳过来的.第二问前缀和即可得(不对啊边走边记录就行了吧我冗了Orz). #include <cstdio> ... 
随机推荐
- DAY17-Ajax
			Ajax准备知识:json 什么是json? 定义: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式. 它基于 ECMAScript ( ... 
- char 与 String 之间的转换
			public class Test { public static void main(String [] args) { char c = 'a'; System.out.println (c); ... 
- Servlet开发中注意的细节问题
			客户端访问服务器的时候是通过URL访问的,所以我们要想用浏览器访问我们的Servlet的时候,我们就需要将我们的Servlet映射到一个URL上(通过我们的web.xml文件中的<servler ... 
- __call()和__callStatic()方法
			__call() 当对象访问不存在的方法时,__call()方法会被自动调用__callStatic() 当对象访问不存在的静态方法时,__callStatic()方法会被自动调用 这两个方法在PHP ... 
- C++使用标准库的栈和队列
			转自http://blog.csdn.net/zhy_cheng/article/details/8090346 使用标准库的栈和队列时,先包含相关的头文件 #include<stack> ... 
- php学习笔记-if else
			生活不会总是波澜不惊的,要是那样也没有什么意思.代码也一样,if else的出现为平静的生活带来一点变化. <?php $money = 1000; if($money>0) { //sl ... 
- 把数据分配到view
- hadoop运行常见问题FAQ
			问题1:Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-outAnswer:程序里面需要打开多个文件,进行分析,系统一般默认数量是 ... 
- nfs搭建和挂载
			1.搭建server a.创建共享目录 mkdir /nfs1 b.vim /etc/sysconfig/nfs 固定端口 c.vim /etc/export /nfs1 192.168.10 ... 
- c#对文件的读写
			最近需要对一个文件进行数量的分割,因为数据量庞大,所以就想到了通过写程序来处理.将代码贴出来以备以后使用. //读取文件的内容 放置于StringBuilder 中 StreamReader sr = ... 
