首页 > 其他分享 >[树形dp]没有上司的舞会

[树形dp]没有上司的舞会

时间:2024-07-06 21:55:11浏览次数:20  
标签:rt 舞会 le int max 树形 节点 dp

题目描述

U r a l Ural Ural 大学有 N N N 名职员,编号分别为 1 ∼ N 1 \sim N 1∼N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 H i H_i Hi​ 给出,其中 1 ≤ i ≤ N 1 \le i \le N 1≤i≤N。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入格式

第一行一个整数 N N N( 1 ≤ N ≤ 6000 1 \le N \le 6000 1≤N≤6000)。
接下来的 N N N 行,每行一个整数 H i H_i Hi​,表示第 i i i 名职员的快乐值 H i H_i Hi​。
接下来的 N − 1 N - 1 N−1 行,每行两个整数 a , b a, b a,b,表示 b b b 是 a a a 的直接上司。

输出格式

输出一行一个整数代表最大的快乐值。

样例

样例输入1

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5

样例输出1

5

数据范围

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 6 × 1 0 3 1 \le N \le 6 \times 10 ^ 3 1≤N≤6×103, − 128 ≤ H i ≤ 127 -128 \le H_i \le 127 −128≤Hi​≤127, 1 ≤ a , b ≤ N 1 \le a, b \le N 1≤a,b≤N,且给出的关系一定是一棵树。

思路

首先,我们很容易想到使用暴力做法,使用 dfs 算法,遍历整棵树,枚举当前节点是否选取,计算快乐值。

显然,这种算法一定会超时。

由于题目在求最大的快乐值,不需要追究过程,我们可以考虑使用 dp 算法。

对于每一个节点,有两种情况:

  1. 当前节点参加舞会,则其子节点不能参加舞会,将子节点不参加舞会的快乐值相加,与 0 0 0 取最大值;
  2. 当前节点不参加舞会,则其子节点可以参加,也不可以参加,将每个节点的两种快乐值取最大值再相加,与 0 0 0 取最大值。

和 0 0 0 取最大值是因为可以一个人也不参加(快乐值可能小于 0 0 0)。

最后的答案是根节点两种情况的最大值。

由此,我们可以开始 dp 了。

划分阶段

用 d p dp dp 数组存储每一个节点的两种情况。

状态设计

设 d p [ x ] [ 0 / 1 ] dp[x][0/1] dp[x][0/1] 表示第 x x x 个节点是否参加舞会, 0 0 0 表示当前节点不参加, 1 1 1 表示当前节点参加。

转移方程

d p [ x ] [ 0 ] = max ⁡ ( 0 , ∑ 1 ≤ i ≤ N max ⁡ ( d p [ i ] [ 0 ] , d p [ i ] [ 1 ] ) ) dp[x][0] = \max(0, \sum_{\mathclap{1 \le i \le N}}\max(dp[i][0], dp[i][1])) dp[x][0]=max(0,1≤i≤N∑​max(dp[i][0],dp[i][1]))

d p [ x ] [ 1 ] = max ⁡ ( 0 , ∑ 1 ≤ i ≤ N d p [ i ] [ 0 ] ) + a [ i ] dp[x][1] = \max(0, \sum_{\mathclap{1\le i \le N}}dp[i][0]) + a[i] dp[x][1]=max(0,1≤i≤N∑​dp[i][0])+a[i]

a n s = max ⁡ ( d p [ r t ] [ 0 ] , d p [ r t ] [ 1 ] ) ans = \max(dp[rt][0], dp[rt][1]) ans=max(dp[rt][0],dp[rt][1])

边界条件

当递归到最底层时,即没有子节点,返回。

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int a[6010];
vector<int> v[6010];//邻接表存图
bool fl[6010];
int f[6010][2];//dp数组
void dfs(int x){
	f[x][1] = a[x];
	f[x][0] = 0;
	for(auto i : v[x]){//遍历v[x](从v[x].begin() 到 v[x].end())
		dfs(i);
		f[x][0] += max(f[i][0], f[i][1]);
		f[x][1] += f[i][0]; 
	} 
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; ++ i){
		scanf("%d", &a[i]);
		fl[i] = 1;
	}

	//连边
	while(1){
		int x, y;
		scanf("%d %d", &x, &y);
		if(x == 0 && y == 0){
			break;
		}
		v[y].push_back(x); 
		fl[x] = 0;
	}
	
	//求根节点
	int rt = 0;
	for(int i = 1; i <= n; ++ i){
		if(fl[i]){
			rt = i;
			break;
		}
	}
	
	//树形dp
	dfs(rt);
	
	printf("%d", max(f[rt][0], f[rt][1]));
	return 0;
}

感谢观看,请勿抄袭!

标签:rt,舞会,le,int,max,树形,节点,dp
From: https://blog.csdn.net/m0_64542522/article/details/140189806

相关文章

  • DP:完全背包问题
    文章目录......
  • 二维dp
    阿里巴巴2023092501题目描述在一个(n×n)的正方形训练场上,每个位置都有一枚硬币。小明从左上角(0,0)出发,跳跃可以按以下方式进行:向右走一步,再向上或向下走两步。向右走两步,再向上或向下走一步。小明不能跳出训练场,也不能往回跳。目标是帮助小明获得尽可能多的硬币......
  • 用免费WordPress和Cloudflare打造媲美收费服务的网站
    你是否曾因为网站搭建的高昂费用而犹豫不决?别担心,我来告诉你一个几乎零成本的解决方案,让你轻松拥有一个功能强大的网站。通过免费域名、免费PHP主机、WordPress程序和CloudflareCDN服务的组合,你可以打造出一个媲美收费服务的网站。首先,你需要一个域名。在lita.eu.org注册免费......
  • FreeRDP使用,快速找出账户密码不正确的服务器地址
    最近有个需求,需要找出服务器未统一设置账户密码的服务器,进行统一设置,一共有一百多台服务器,一个个远程登录看,那得都费劲啊,这时候就可以用到FreeRDP这个远程桌面协议工具,FreeRDP下载,根据自己的需要下载,我是windows1064位系统就下载了个wfreerdp,下载好了之后就可以写代码了......
  • 四种封装 ThreadPoolExecutor 的线程池的使用以及直接使用 ThreadPoolExecutor ,优缺点
    池化思想:线程池、字符串常量池、数据库连接池提高资源的利用率下面是手动创建线程和执行任务过程,可见挺麻烦的,而且线程利用率不高。手动创建线程对象执行任务执行完毕,释放线程对象线程池的优点:提高线程的利用率提高程序的响应速度便于统一管理线程对象可以控制最大并发......
  • Python多线程-线程池ThreadPoolExecutor
    1.线程池不是线程数量越多,程序的执行效率就越快。线程也是一个对象,是需要占用资源的,线程数量过多的话肯定会消耗过多的资源,同时线程间的上下文切换也是一笔不小的开销,所以有时候开辟过多的线程不但不会提高程序的执行效率,反而会适得其反使程序变慢,得不偿失。为了防止无尽的线程......
  • P8592 『JROI-8』颅脑损伤 2.0(加强版)(线性 dp + 单调队列优化)
    P8592『JROI-8』颅脑损伤2.0(加强版)线性dp+单调队列优化最优化问题,考虑dp。先离散化,按左端点排序,设\(f_i\)表示考虑完前\(i\)条线段符合条件的染色,最小长度和。转移枚举上一条红色线段\(j\),\(f_i=f_j+len_i\)。当然\(j\)需要满足题目的条件,即\((j,i)\)中的黑色线......
  • 从零开始使用WordPress搭建个人网站并一键发布公网详细教程
    文章目录前言1.搭建网站:安装WordPress2.搭建网站:创建WordPress数据库3.搭建网站:安装相对URL插件4.搭建网站:内网穿透发布网站4.1命令行方式:4.2.配置wordpress公网地址5.固定WordPress公网地址5.1.固定地址访问WordPress前言本文主要介绍如何在LinuxUbuntu......
  • 小国王 骑士 状态压缩DP
    //小国王.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。//#include<iostream>#include<vector>usingnamespacestd;/*https://loj.ac/p/10170http://ybt.ssoier.cn:8088/problem_show.php?pid=1592在nxn的棋盘上放k个国王,国王可攻击相邻的......
  • 远程桌面协议(RDP)
    原文链接:https://zhuanlan.zhihu.com/p/679953523在信息化社会中,远程工作、协作和管理已成为常态。远程桌面协议(RemoteDesktopProtocol,简称RDP)作为一种关键技术,为用户提供了如同身临其境般的远程计算机操作体验。那么,究竟什么是RDP?它又如何赋能我们的日常工作与生活呢?揭开RDP......