树形压缩DP——没有上司的舞会

news2024/11/14 15:17:47

树形压缩DP——没有上司的舞会

  • 一、问题描述
  • 二、DFS暴搜
    • 1、算法思路
    • 2、代码实现
  • 三、DP做法

一、问题描述

在这里插入图片描述

二、DFS暴搜

1、算法思路

这道题其实最容易想到的是暴力DFS,然后选出一个最大值。我们平时会在DFS的形参中设置一个变量表示子树的根。但是今天这道题还涉及到你是否选当前的形参中的根节点。

凡是用DFS,我们都要明确这个函数的作用,而明确了作用之后,我们才方便写递归。

我们这里的DFS函数的作用就是:

在根节点选或者不选的条件下,分别计算出子树中的快乐指数的最大值。

2、代码实现

#include<iostream>
#include<cstring>
using namespace std;
const int N=60010,M=3*N;
int hap[N];
int h[N],e[M],ne[M],idx;
int n;
void add(int x,int y)
{
    e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}
int dfs(int u,int x)
{
    if(h[u]==-1)return 0;
    int ans=0;
    if(!x)
        for(int i=h[u];i!=-1;i=ne[i])
            ans+=max(dfs(e[i],0),dfs(e[i],1)+hap[e[i]]);
    else
        for(int i=h[u];i!=-1;i=ne[i])
            ans=ans+dfs(e[i],0);
    return ans;
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",hap+i);
    int r=1;//r是用来寻找根节点的
    for(int i=0;i<n-1;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(b,a);
        if(a==r)r=b;
    }
    int res=max(dfs(r,0),dfs(r,1)+hap[r]);
    cout<<res<<endl;
    return 0;
}

这种方法非常好想,但是效率非常的慢,已经超时了。

为什么慢?因为很多问题出现了重复搜索的现象,我们以样例为例子:(我们输出调用函数时的形参)
在这里插入图片描述

我们发现,一个如此简单的样例,里面都有2组函数发生了两次重复。当数据量增大的时候,重复的次数会非常多。

三、DP做法

这次我们换一种方式,为了解决DFS重复计算的问题,我们可以采用随搜随记的方式来记录。这样的话,我们可以直接查表,但是不管怎么样,都需要遍历一遍二叉树,但是我们优化之后可以保证只遍历一次。

那么我们就用 f [ u ] [ 2 ] f[u][2] f[u][2]来记录。

#include<iostream>
#include<cstring>
using namespace std;
const int N=6010;
int n;
int h[N],e[N],ne[N],idx;
int hap[N];
int f[N][2];
void dfs(int u)
{
    f[u][1]=hap[u];
    for(int i=h[u];i!=-1;i=ne[i])
    {
        dfs(e[i]);
        f[u][0]+=max(f[e[i]][1],f[e[i]][0]);
        f[u][1]+=f[e[i]][0];
    }
}
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int main()
{
     scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &hap[i]);
    memset(h, -1, sizeof h);
    int root=1;
    for (int i = 0; i < n - 1; i ++ )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        add(b, a);
        if(a==root)root=b;
    }
    dfs(root);
    cout<<max(f[root][0],f[root][1]);
    return 0;
}

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

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

相关文章

mysql的事务和锁

【MySQL事务和锁】 学习原文&#xff1a;https://blog.csdn.net/zly03/article/details/127170995 事务四大特性&#xff1a;原子性、一致性、隔离性、持久性&#xff0c;简称ACID MySQL中支持3种不同的存储引擎&#xff1a; MyISAM存储引擎、Memory存储引擎、和InnoDB存储引…

CMake使用外部动态库/静态库和头文件

CMake使用外部动态库/静态库和头文件一、准备工作二、新建一个新的CMake工程三、开始构建四、为target添加共享库五、链接静态库一、准备工作 在博文《使用CMake构建静态库和动态库》中已经介绍了libhello动态库的构建和安装&#xff0c;现在我们看看如何使用这个外部动态库。…

iOS 15.0+ 中 SwiftUI 顶部或底部悬浮功能小面板的极简实现

功能需求 我们有时需要在 App 主视图的顶部或底部固定悬浮放置一个功能视图: 如上图所示,我们将一个列表项目输入小面板按需放在主视图的顶部或底部: 当放置在顶部时,解决了其对导航栏(NavigationView)中 toolbar 内容的遮挡问题;当放置在底部时,考虑到了其对列表最后…

spring boot 实现搜索引擎的设计思想

目录 实现思路 索引模块 预处理 对文档进行分词 搜索模块 实现思路 索引构建模块 搜索模块 数据库模块 索引模块 对于搜索一个东西&#xff0c;我们很自然的能想到遍历去查找。比如我要查找一本书叫 《红楼梦》&#xff0c;那么我直接在所有结果中进行遍历查找&#xff…

druid解析-过滤器详解

druid支持过滤器&#xff0c;可以在获取连接或者调用连接对象的方法时&#xff0c;先调用过滤器&#xff0c;之后再执行底层方法&#xff0c;比如DruidDataSource的getConnection()方法&#xff1a; public DruidPooledConnection getConnection(long maxWaitMillis) throws SQ…

网络安全一哥的奇安信发布了全球高级可持续威胁年度报告 值得学习

声明 本文是学习全球高级持续性威胁 APT 2021年度报告. 下载地址而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 中国境内高级持续性威胁综述 基于中国境内海量DNS域名解析和奇安信威胁情报中心失陷检测&#xff08;IOC&#xff09;库的碰撞分析&…

9_1、Java基本语法之常用类String、StringBuffer、StringBuilder的使用

一、String的使用及常用方法 1、概述 String:表示字符串&#xff0c;使用""引起来。 1.1、String类是声明为final的&#xff0c;不可被继承。 1.2、String类实现了Serializable接口&#xff0c;表示字符串支持序列化。 …

【王道操作系统】2.1.3 原语实现对进程的控制

原语实现对进程的控制 文章目录原语实现对进程的控制1.什么是进程控制2.原语实现对进程的控制3.回忆进程的组织4.进程控制大致图解5.进程控制原语的相同点6.进程控制的五种原语1.什么是进程控制 2.原语实现对进程的控制 3.回忆进程的组织 4.进程控制大致图解 这里说明一下调度和…

MySQL【AUTO_INCREMENT 】自增列

使用案例场景再现&#xff1a; 创建一个为test的数据库&#xff0c;为数据库test创建一个数据表student &#xff0c;其中包含的字段有 id name sex&#xff0c;admission_time,其中要求student表中的人员id必须连续排列。 create database test use test cr…

SCI论文解读复现【NO.1】基于Transformer-YOLOv5的侧扫声纳图像水下海洋目标实时检测

此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;帮助…

三旗舰焕新发布引领品牌向上 长城汽车登陆2022广州车展

近日&#xff0c;长城汽车携哈弗、魏牌、欧拉、坦克、长城炮以及沙龙六大品牌&#xff0c;登陆第二十届广州国际汽车展览会&#xff08;以下简称“2022广州车展”&#xff09;。魏牌全新旗舰蓝山DHT-PHEV、坦克500 PHEV长续航版、大型高性能豪华皮卡山海炮等车型联袂而至&#…

创建静态库存文件 ansible(3)

目录 创建一个名为/home/student/ansible/inventory的静态库存文件如下所示&#xff1a; &#xff08;1&#xff09;node1是dev主机组的成员 &#xff08;2&#xff09;node2是test主机组的成员 &#xff08;3&#xff09;node1和node2是prod主机组的成员 &#xff08;4&am…

【Qt】控件——QPlainTextEdit使用简单介绍:常用方法及信号、逐行读取编辑框的内容、使用自带的快捷菜单、作为日志显示窗口

Qt控件-QPlainTextEdit使用 参考链接&#xff1a; https://blog.csdn.net/seniorwizard/article/details/109726147; https://blog.csdn.net/seniorwizard/article/details/109726147 文章目录Qt控件-QPlainTextEdit使用QPlainTextEdit控件简单介绍1. 逐行读取文本编辑框的内容…

【PCB专题】什么是金属化孔(PTH)和非金属化孔(NPTH)

计出来的,并不是放在那里好看的,每个不同的孔洞都有其目的。一般来说孔洞越多,PCB的成本也越高。 PCB中的孔类型大体上可以被区分为PTH(Plating Through Hole)电镀导通孔,和NPTH(None Plating Through Hole)非电镀导通孔两大类。这里说的通孔是指从PCB的一面直接贯穿到…

Spark数据倾斜性能调优

目录 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 某个task执行特别慢的情况 某个task莫名其妙内存溢出的情况 查看导致数据倾斜的key的数据分布情况 知识拓展 coalesce 和 repartition 的区别 数据倾斜的解决方案 解决方案一&am…

【哈工大大一年度项目经验与感想】立项篇 中(2021.9.17~2021.11.17)

第四步&#xff1a;立项报告书写 立项报告的目的在于向答辩老师或者投资方阐述你的项目是什么&#xff1f;做什么的&#xff1f;解决什么问题&#xff1f;打算怎么解决这些问题&#xff1f;有什么创新点、特色&#xff1f;目标&#xff1f;所以一篇立项报告正文需要包括以下内容…

21级数据结构考前模拟题

说明&#xff1a; 此试卷为21级数据结构考前模拟题&#xff0c;老师并未给出标准答案&#xff0c;故以下所有答案均为博主给出&#xff0c;并只供参考&#xff0c;不保证其正确性&#xff01;&#xff01;&#xff01; 只更新了部分&#xff0c;还在写题中&#xff01;&#xf…

同步+异步日志系统(C++实现)

对于一个服务器而言&#xff0c;不论是在调试中还是在运行中&#xff0c;都需要通过打日志的方式来记录程序的运行情况。本文设计的日志系统实现了同步与异步两种功能&#xff0c;原理见下图&#xff1a; 同步日志&#xff1a;日志写入函数与工作线程串行执行&#xff0c;由于涉…

人脸识别与美颜算法实战-基于机器学习的人脸识别

机器学习根据输出的类型一般分为两类,分类和回归。分类的输出一般是离散值,回归输出的值一般是连续的。比如,人脸识别这种就属于分类问题,房价预测一般是一个回归问题。 鸢尾花分类 # -*- coding: UTF-8 -*- # 导入数据集 from sklearn.datasets import load_iris iris =…

InnoDB事务原理理解(redo log,undo log,锁,MVCC的理解)

目录事务事务的四大特性ACID事务相关SQL语句事务原理事务如何解决隔离性隔离性总结事务如何解决原子性、一致性、持久性redo log 重做日志CheckPoint 检查点机制Double Writer 双写磁盘undo log 回滚日志锁表级锁表读锁、表写锁元数据锁MDL意向锁行级锁行读锁&#xff0c;行写锁…