算法笔记_076:蓝桥杯练习 结点选择(Java)
目录
1 问题描述
有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?
第一行包含一个整数 n 。
接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。
接下来一共 n-1 行,每行描述树上的一条边。
1 2 3 4 5
1 2
1 3
2 4
2 5
对于20%的数据, n <= 20。
对于50%的数据, n <= 1000。
对于100%的数据, n <= 100000。
权值均为不超过1000的正整数。
2 解决方案
本题主要考查动态规划法,核心在于如何构造状态转移方程。
引用参考资料2中讲解:
DP, 用dp[i][0]表示不选择i点时,i点及其子树能选出的最大权值,dp[i][1]表示选择i点时,i点及其子树的最大权值。
状态转移方程:
对于叶子节点 dp[k][0] = 0, dp[k][1] = k点权值
对于非叶子节点i,
dp[i][0] = ∑max(dp[j][0], dp[j][1]) (j是i的儿子)
dp[i][1] = i点权值 + ∑dp[j][0] (j是i的儿子)
最大权值即为max(dp[0][0], dp[0][1])
下面的代码最终运行评分为50分,具体原因:运行超时。不过文末参考资料1中C++代码运行评分为100分(PS:具体理解可以参考文末参考资料1)。看了参考资料1中代码,让我对题意的理解变为:其中输入n-1条表示边的两个数,是具体的第i个顶点和第j个顶点,不是具体顶点的权值;在第一次做的时候,我理解为具体顶点的权值。

具体代码如下:
import java.util.Scanner;
public class Main {
public int[][] dp = new int[100002][2];
public int[][] tree = new int[100002][300]; //tree[i][3] = num表示第i个节点的第3个孩子节点为第num个节点
/*
* 参数point1:表示输入的第point1个节点,不是节点权值
* 参数point2:表示输入的第point2的节点,不是节点权值
* 说明:由于题目仅仅给出边的说明,并未说明两个节点谁是父母节点,所以以下有两种情形
*/
public void creatTree(int point1, int point2) {
int i = 0;
//当第point1个节点为父母节点时
while(tree[point1][i] != 0) i++; //如果第point1个节点已经有孩子了,再增加一个孩子
tree[point1][i] = point2;
int j = 0;
//当第point2个节点为父母节点时
while(tree[point2][j] != 0) j++;
tree[point2][j] = point1;
}
/*
* 参数satrt:开始对树进行DFS遍历的开始节点,为具体节点位置,不是节点权值
* 参数root:为第start个节点的直接父母节点位置,root = 0表示根节点的父母节点
*/
public void dfs(int start, int root) {
int child = tree[start][0]; //第start个节点的第1个孩子节点
for(int i = 0;child != 0;i++) {
child = tree[start][i];
if(child != root) { //防止出现start的孩子成为start的父亲情况
dfs(child, start);
dp[start][1] += dp[child][0]; //当第child个节点没有孩子节点时,开始回溯
dp[start][0] += (dp[child][1] > dp[child][0] ? dp[child][1] : dp[child][0]);
}
}
}
public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i = 0;i < n;i++)
test.dp[i + 1][1] = in.nextInt();
for(int i = 0;i < n - 1;i++) {
int point1 = in.nextInt();
int point2 = in.nextInt();
test.creatTree(point1, point2);
}
test.dfs(1, 0); //从创建的数的根节点(即第1个顶点,0表示根节点的父母节点)开始进行DFS遍历
int max = (test.dp[1][1] > test.dp[1][0] ? test.dp[1][1] : test.dp[1][0]);
System.out.println(max);
}
}
参考资料:
2. 蓝桥杯 - 算法训练 - ALGO - 4 结点选择 (经典树形DP)
算法笔记_076:蓝桥杯练习 结点选择(Java)的更多相关文章
- 算法笔记_052:蓝桥杯练习Multithreading(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 现有如下一个算法: repeat ni times yi := y y := yi+1 end repeat 令n[1]为你需要算加法的第 ...
- 算法笔记_083:蓝桥杯练习 合并石子(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数.求把所有石子 ...
- 算法笔记_107:蓝桥杯练习 算法提高 学霸的迷宫(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗.但学霸为了不要别人打扰,住在一个城堡里,城堡外面是一个二维的格子迷宫,要 ...
- 算法笔记_096:蓝桥杯练习 算法提高 求最大值(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大.并且要求你选定的数对的ai之和非负,bi之和非负 ...
- 算法笔记_055:蓝桥杯练习 Tricky and Clever Password (Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 在年轻的时候,我们故事中的英雄——国王 Copa——他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好 ...
- 算法笔记_067:蓝桥杯练习 算法训练 安慰奶牛(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路.道路被用来连接N个牧场,牧场被连续地编号为1到N.每一个牧场都是 ...
- 算法笔记_091:蓝桥杯练习 递推求值(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 已知递推公式: F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5, F(n, 2)=F(n-1, 1) + 3F(n- ...
- 算法笔记_056:蓝桥杯练习 未名湖边的烦恼(Java)
目录 1 问题描述 2 解决方案 2.1 递归法 2.2 递推法 1 问题描述 问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰 ...
- 算法笔记_060:蓝桥杯练习 出现次数最多的整数(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 编写一个程序,读入一组整数,这组整数是按照从小到大的顺序排列的,它们的个数N也是由用户输入的,最多不会超过20.然后程序将对这个数组进行统 ...
随机推荐
- 洛谷P2224 [HNOI2001] 产品加工 [DP补完计划,背包]
题目传送门 产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时 ...
- 按照grouip分组,之后分组调用生成正式凭证 的接口
按照grouip分组,之后分组调用生成正式凭证 的接口 Map<String, List<OperatingLogVO>> resultMap = new HashMap< ...
- 循序渐进PYTHON3(十三) --7-- DJANGO之MODELS
一.使用django连库建表 使用django连接数据库需要知道3个要点: 1.通过settings.py注册当前app: 2.通过settings.py配置连接某种类型的数据库: 3.通过m ...
- WQS二分题集
WQS二分,一种优化一类特殊DP的方法. 很多最优化问题都是形如“一堆物品,取与不取之间有限制.现在规定只取k个,最大/小化总收益”. 这类问题最自然的想法是:设f[i][j]表示前i个取j个的最大收 ...
- 调用sort段错误问题
问题:sort的比较函数实现有问题导致进程调用sort时core了. 结论:特别要注意,sort的比较函数必须遵循严格弱排序(strict weak ordering)的规则. 这是最近在工作中遇 ...
- 【最大流Dinic模板】HDU1532&POJ1273-Drainage Ditches(16/3/6更正)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...
- android系统各种音量的获取与设置
获取系统音量 通过程序获取android系统手机的铃声和音量.同样,设置铃声和音量的方法也很简单! 设置音量的方法也很简单,AudioManager提供了方法: publicvoidsetStream ...
- 1.3 (JavaScript学习笔记)JavaScript对象
在JavaScript中所有事物都是对象,字符串.数值.数组.函数...等, JavaScript还允许自定义对象.这些在1.1中有所介绍. 一.遍历对象属性 <!DOCTYPE html> ...
- iOS \U6b3e转字符串
-(NSString *)replaceUnicode:(NSString *)unicodeStr { NSString *tempStr1 = [unicodeStr stringByReplac ...
- oracle 性能优化建议
原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHER ...