每周一算法:树形动态规划

news2024/11/16 17:43:40

树形动态规划

树形动态规划一般用于处理求树上最优值的问题。大多数动态规划问题都是在一维二维这种规则的背景下的,可以解决的问题比较局限,而树作为一种特殊的图,可以描述比较复杂的关系,再加上树的递归定义,是一种非常合适进行动态规划处理的数据结构。

具体来说,在树形动态规划当中,一般先算子树再进行合并。与树的后序遍历相似,都是先遍历子树,遍历完之后将子树的值传给父亲。简单来说就是先递归访问所有子树,再在根上合并。

了解了树形动态规划的基本思想后,下面来看一个树形动态规划的例题。

经典例题

题目链接

没有上司的舞会

题目描述

某大学有 n n n 个职员,编号为 1 … n 1\ldots n 1n

他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。

现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 h i h_i hi,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式

输入的第一行是一个整数 n n n

2 2 2 到第 ( n + 1 ) (n + 1) (n+1) 行,每行一个整数,第 ( i + 1 ) (i+1) (i+1) 行的整数表示 i i i 号职员的快乐指数 h i h_i hi

( n + 2 ) (n + 2) (n+2) 到第 2 n 2n 2n 行,每行输入一对整数 l , k l, k l,k,代表 k k k l l l 的直接上司。

输出格式

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

样例 #1

样例输入 #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\leq n \leq 6 \times 10^3 1n6×103 − 128 ≤ h i ≤ 127 -128 \leq h_i\leq 127 128hi127 1 ≤ l , k ≤ n 1 \leq l, k \leq n 1l,kn,且给出的关系一定是一棵树。

算法思想

从给出的测试样例,可以构建出这样一棵树。

在这里插入图片描述
从图中可以看出, 1 、 2 1、2 12的上司是 3 3 3 6 、 7 6、7 67的上司是 4 4 4,如果 3 、 4 3、4 34不参加舞会的话,邀请 1 、 2 、 5 、 6 、 7 1、2、5、6、7 12567,可以使快乐指数最大为 5 5 5。由此可见:

  • 对树中每个结点有 2 2 2种选择,邀请或者不邀请
  • 结点的选择与否会影响其子结点:某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会

因此,在状态表示时需要考虑树的整体收益,以及结点的状态(邀请或者不邀请)。

状态表示

  • f [ i ] [ 0 ] f[i][0] f[i][0]表示以 i i i为根的子树,在不邀请根结点 i i i时的最大快乐指数
  • f [ i ] [ 1 ] f[i][1] f[i][1]表示以 i i i为根的子树,在邀请根结点 i i i时的最大快乐指数

不妨设整棵树的根结点为 r r r,那么最终答案是 f [ r ] [ 0 ] f[r][0] f[r][0] f [ r ] [ 1 ] f[r][1] f[r][1]的最大值。

状态计算

对于 i i i为根的子树,考虑当前的根结点 i i i的状态:

  • 如果不邀请 i i i,那么可以选择邀请或者不邀请其子结点 j j j,因此可以递归计算出 f [ j ] [ 0 ] f[j][0] f[j][0] f [ j ] [ 1 ] f[j][1] f[j][1],取二者的最大值进行累加,即 f [ i ] [ 0 ] = ∑ m a x ( f [ j ] [ 0 ] , f [ j ] [ 1 ] ) f[i][0]=\sum max(f[j][0],f[j][1]) f[i][0]=max(f[j][0],f[j][1]),其中 j j j i i i的所有子结点。
  • 如果邀请 i i i,那么不能邀请其子结点 j j j,因此可以递归计算出 f [ j ] [ 0 ] f[j][0] f[j][0] f [ i ] [ 0 ] = ∑ ( f [ j ] [ 0 ] ) f[i][0]=\sum (f[j][0]) f[i][0]=(f[j][0]),其中 j j j i i i的所有子结点。

初始状态

f [ i ] [ 1 ] f[i][1] f[i][1]表示在邀请根结点 i i i时的最大快乐指数,其初始值为 h [ i ] h[i] h[i]

时间复杂度

由于在递归的过程每个点都只会算一次,所以总的时间复杂度为 O ( n ) O(n) O(n)

代码实现

#include <iostream>
#include <vector>
using namespace std;

const int N = 6010;
int h[N]; //快乐指数
int fa[N]; //保存每个结点的父节点
//邻接表存储树
vector<int> g[N];
//f[i][0]表示以i为根的子树,在不邀请根结点i时的最大快乐指数
//f[i][1]表示以i为根的子树,在邀请根结点i时的最大快乐指数
int f[N][2];
void dfs(int i)
{
    f[i][1] = h[i]; //初始状态
    for(int j : g[i]) //遍历i的子结点
    {
        dfs(j); //递归计算以j为根的子树
        f[i][0] += max(f[j][0], f[j][1]);
        f[i][1] += f[j][0];
    }
}
int main()
{
    int n;
    cin >> n;
    //输入快乐指数
    for(int i = 1; i <= n; i ++) cin >> h[i];
    //构建树
    for(int i = 1; i < n; i ++)
    {
        int a, b;
        cin >> a >> b;
        g[b].push_back(a); //a是b的子结点
        fa[a] = b; //a的父节点是b
    }
    //确定根结点
    int r = 1;
    while(fa[r]) r = fa[r];
    dfs(r);
    cout << max(f[r][0], f[r][1]);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1314517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux-CentOS7(无图形界面版)部署stable-diffusion-webui 全过程

Linux-CentOS7&#xff08;无图形界面版&#xff09;部署Stable Diffusion webui 全过程 前置要求 git的版本不能是CentOS默认的版本&#xff08;1.8&#xff09;&#xff0c;版本太老&#xff0c;在后面安装过程会失败。去github上下载最新的git源码包 安装成功显示版本号 …

用重建大师集群跑模型,在哪里可以设置联机?

答&#xff1a;工程路径、照片路径&#xff0c;引擎路径均设置为网络IP方式的路径&#xff0c;集群内的引擎都设置一样的路径就可以集群处理了。 重建大师是一款专为超大规模实景三维数据生产而设计的集群并行处理软件&#xff0c;输入倾斜照片&#xff0c;激光点云&#xff0c…

磁盘坏道扫描工具 Macrorit Disk Scanner v6.7.0 中文免费版 -供大家学习研究参考

非常方便实用的磁盘坏道修复软件。Wipe Bad Disk功能强大好用&#xff0c;通过特殊的算法来强制将硬盘的坏道删除清空格式化&#xff0c;从而拯救因产生坏道而不敢继续使用的硬盘!要注意的是经过这块软件清空的硬盘数据基本上是不能被恢复的&#xff0c;所以操作前请一定要备份…

【深度学习目标检测】七、基于深度学习的火灾烟雾识别(python,目标检测,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…

基于Nexus搭建Maven私服基础入门

什么是Nexus&#xff1f;它有什么优势&#xff1f; 要了解为什么需要nexus的存在&#xff0c;我们不妨从以下几个问题来简单了解一下: 为什么需要搭建私服&#xff1f;如果没有私服会出现什么问题&#xff1f; 对于企业开发而言&#xff0c;如果没有私服&#xff0c;我们所有…

uniGUI for Delphi UniSweetAlert控件详解

UniSweetAlert是UniGUI后期版本新增的一个界面友好的消息提示和输入控件&#xff0c;是ShowMessageN的升级版&#xff0c;UniSweetAlert增加了更多的可控制属性。 属性介绍 1、AlertType&#xff1a;提示类型&#xff0c;分为atError、atSuccess、atInfo、atQuestion、atWarni…

JavaSE语法之七:封装

文章目录 一、封装的概念二、访问限定符三、封装扩展之包1. 包的概念2. 导入包中的类3. 自定义包4. 常见的包 四、实现封装五、static成员1. 再谈学生类成员变量2. static修饰成员变量3. static修饰成员方法4. static成员变量初始化 六、代码块1. 代码块概念及其分类2. 普通代码…

【VMware安装及虚拟机配置】

1. 下载VMware 进入 VMware Workstation 17 Pro下载链接 下拉到如下位置&#xff0c;点击DOWNLOAD 2. 安装VMware 参考&#xff1a;虚拟机VMware下载与安装教程 本次安装是vmware 17&#xff0c;安装步骤差不多&#xff0c;只参考第二部分即可。 3. 激活VMware 密钥&…

version `GLIBC_2.29‘ not found 的原因和怎么解决问题

程序上经常有在这台Linux上编译&#xff0c;然后放到另一个Linux上运行的情况。 如果Linux版本差别不大或都是ubuntu或centos系列还好。 如果不是一个系列很容易出现GLIBC 找不到的情况。 尤其是ubuntu上编译&#xff0c;然后放到centos系列。因为centos为了追求所谓的稳定&…

计算机组成原理-选择语句和循环语句的汇编表示

文章目录 选择语句jmpjxx示例&#xff1a;选择语句的机器级表示扩展&#xff1a;cmp指令的底层原理 循环语句使用条件转移指令实现循环用loop指令实现循环 选择语句 不一定知道指令的位置&#xff0c;所以jmp直接跳转到指令的位置很难办 jmp 标号相当于位置&#xff0c;名字…

生产派工自动化:MES系统的关键作用

随着制造业的数字化转型和智能化发展&#xff0c;生产派工自动化成为了提高生产效率、降低成本&#xff0c;并实现优质产品生产的关键要素之一。制造执行系统&#xff08;MES&#xff09;在派工自动化中发挥着重要作用&#xff0c;通过实时数据采集和智能调度&#xff0c;优化生…

Ubuntu虚拟机怎么设置静态IP

1 首先先ifconfig看一下使用的是哪个网络接口&#xff1a; 2 编辑 sudo vi /etc/netplan/00-installer-config.yamlnetwork:ethernets:ens33: # 根据您的网络接口进行修改&#xff0c;有的是eth0&#xff0c;有的是ens33&#xff0c;具体看第一步显示的是哪个网络接口addres…

【答案】2023年国赛信息安全管理与评估第三阶段夺旗挑战CTF(网络安全渗透)

【答案】2023年国赛信息安全管理与评估第三阶段夺旗挑战CTF&#xff08;网络安全渗透&#xff09; 全国职业院校技能大赛高职组信息安全管理与评估 &#xff08;赛项&#xff09; 评分标准 第三阶段 夺旗挑战CTF&#xff08;网络安全渗透&#xff09; *竞赛项目赛题* 本文…

【算法与数据结构】53、LeetCode最大子数组和

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;程序一共两个变量&#xff0c;一个result一个count。result用来记录最终的结果&#xff0c;count记录当…

针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法

针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法 文章目录 针对基于nohup后台运行PyTorch多卡并行程序中断问题的一种新方法Abstractscreen和tmux介绍tmux常用命令以及快捷键Byobu简单操作步骤集锦参考文献 Abstract PyTorch多卡并行运行程序is one of the mos…

Leetcode sql50基础题最后的4题啦

算是结束了这个阶段了&#xff0c;之后的怎么学习mysql的方向还没确定&#xff0c;但是不能断掉&#xff0c;而且路是边走边想出来的。我无语了写完了我点进去看详情都不让&#xff0c;还得重新开启计划&#xff0c;那我之前的题解不都没有了&#xff01;&#xff01; 1.第二高…

Winform高效获取控件(Control)方法 + 源码分析

背景&#xff1a;风好大&#xff0c;睡觉有点怕&#xff0c;起床敲代码了 之前学的都是都是通过遍历控件&#xff08;Controls&#xff09;&#xff0c;判断控件名是否相等来获取Control 其实直接通过:Controls["控件名"]&#xff0c;就可以获得需要的控件 为什么呢…

【Java JVM】运行时数据区

JVM 在执行 Java 程序的过程中会把它管理的内存分为若干个不同的数据区域, 这些区域有着各自的用途。 根据《Java虚拟机规范》中规定, JVM 所管理的内存大致包括以下几个运行时数据区域, 如图所示: 这个运行时数据区被分为了 5 大块 方法区 (Method Area)堆 (Heap)虚拟机栈 (V…

npm ,yarn 更换使用国内镜像源,阿里源,清华大学源

在平时开发当中&#xff0c;我们经常会使用 Npm&#xff0c;yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的&#xff0c;如果没有梯子的话。会感觉特别特别慢&#xff0c;所以&#xff0c;使用国内的源是非常有必要的。 在这里插入图片描述 Nnpm&#xff0c; yarn …

我的NPI项目之Android 安全系列 -- 先认识一下ST33Jxxx

目前接触过的高通平台都没有集成单独的SE&#xff0c;安全运行环境都是高通自家的TEE&#xff0c;又言Trustzone。高通Keystore功能也是依赖TEE来实现的。那么&#xff0c;如果另外集成SE&#xff0c;那么高通的Keystore如何集成&#xff1f;TEE部分要如何配置&#xff1f; 最近…