力扣370周赛 -- 第三题(树形DP)

news2024/12/29 10:30:51

该题的方法,也有点背包的意思,如果一些不懂的朋友,可以从背包的角度去理解该树形DP

问题

题解主要在注释里

         //该题是背包问题+树形dp问题的结合版,在树上解决背包问题

         //背包问题就是选或不选当前物品

         //本题求的是最大分数

         //先转成背包问题理解

         //从n个物品当中选出最大分数

         //再转成有限制版的

         //从n个物品当中选出最大分数,并且血量是健康的

         //再转成树形DP去理解该问题

         

         //树是健康就是,在任意一条树的路径下(到叶子节点的任意一条路径),能确保至少有一个物品不被选

         //从树上前n个物品当中选出一些物品,并且保证树是健康的

         //从树上前i个物品当中选出保证树是健康的前提下,能选出的不超过i个物品的最大分数

         //然后再去拓展这个定义

         

         //结合树形DP的经验

         //以当前u为根节点的子树,在保证树是健康的前提下,能选出的最大分数

         //那么就有了推导过程,从下往上推导,也就是从最小子树往上推导到最大子树最大分数

         //那么最好的做法就是利用递归的特性,回溯的时候进行推导

         //这题中我们直接找出最大分数,其实是比较难的,我们用初中的思想

         //正难则反,既然找最大分数(有个不选的)比较难,那么我们可以用

         //找个最小分数(选上的),那么就变得比较简单了

         

         //状态定义

         //首先我们找最小的,以树形dp为经验推导出

         //我们以u为根节点的子树,总和最小的分数(并且是保证健康的,在一条路径上最少也得选一个)

         //定义为min_val[u]

               

         //那么怎么算出最大分数呢,既然有min_val[u],那么就有,以当前u为根节点的子树节点总和sum_val[u]

         //那么相减sum_val[u] - min_val[u]就等于最大分数了

         

         //那么如何推导这两个定义的数组呢?

         //树形dp类型问题,最好首先用dfs,边回溯边推导数组

class Solution {
public:
 
    void dfs_sum_val(int u,int fa,vector<int>& val,vector<vector<int>>& g,vector<long long>& sum_val)
    {
         sum_val[u] = val[u];
         for(auto e:g[u])
           if(fa != e)//不要往上计算,我们是从下往上推导,并且可以保证不会无限递归
           {
              dfs_sum_val(e,u,val,g,sum_val);
              //回溯计算
              sum_val[u] += sum_val[e];
           }
        
        //这个dfs我们可以算作一个小题,就是计算出每个点为根节点的子树的总和
    }

    void dfs_min_val(int u,int fa,vector<int>& val,vector<vector<int>>& g,vector<long long>& min_val)
    {
          long long min_res = 0;
          min_val[u] = (long long)val[u];//只有一个节点的时候必选

          for(auto& e:g[u])
          {
             if(fa != e)
             {
                 dfs_min_val(e,u,val,g,min_val);
                 min_res += min_val[e];
             }
          }
          if(min_res) min_val[u] = min((long long)min_val[u],min_res);
          //怎么选最小的分数呢,当前根节点选,那么子节点可以不选,当前根节点不选,那么子节点都要选
          //从下往上推导
    }

    long long maximumScoreAfterOperations(vector<vector<int>>& edges, vector<int>& values) 
    {
         //该题是背包问题+树形dp问题的结合版,在树上解决背包问题
         //背包问题就是选或不选当前物品

         //本题求的是最大分数
         //先转成背包问题理解
         //从n个物品当中选出最大分数
         //再转成有限制版的
         //从n个物品当中选出最大分数,并且血量是健康的
         //再转成树形DP去理解该问题
         
         //树是健康就是,在任意一条树的路径下(到叶子节点的任意一条路径),能确保至少有一个物品不被选
         //从树上前n个物品当中选出一些物品,并且保证树是健康的
         //从树上前i个物品当中选出保证树是健康的前提下,能选出的不超过i个物品的最大分数
         //然后再去拓展这个定义
          
         //结合树形DP的经验
         //以当前u为根节点的子树,在保证树是健康的前提下,能选出的最大分数
         //那么就有了推导过程,从下往上推导,也就是从最小子树往上推导到最大子树最大分数
         //那么最好的做法就是利用递归的特性,回溯的时候进行推导

         //这题中我们直接找出最大分数,其实是比较难的,我们用初中的思想
         //正难则反,既然找最大分数(有个不选的)比较难,那么我们可以用
         //找个最小分数(选上的),那么就变得比较简单了
         
         //状态定义
         //首先我们找最小的,以树形dp为经验推导出
         //我们以u为根节点的子树,总和最小的分数(并且是保证健康的,在一条路径上最少也得选一个)
         //定义为min_val[u]
               
         //那么怎么算出最大分数呢,既然有min_val[u],那么就有,以当前u为根节点的子树节点总和sum_val[u]
         //那么相减sum_val[u] - min_val[u]就等于最大分数了
         
         //那么如何推导这两个定义的数组呢?
         //树形dp类型问题,最好首先用dfs,边回溯边推导数组
         
  
         int edge_size = edges.size();
         vector<vector<int>> g(values.size() + 110);
    
         for(int i = 0;i < edge_size;i++)
         {
             int a = edges[i][0];
             int b = edges[i][1];
             g[a].push_back(b);
             g[b].push_back(a);
         }

         vector<long long> sum_val(21000);
         vector<long long> min_val(21000,0x3f3f3f3f);
         //预处理出来sum_val数组
         dfs_sum_val(0,-1,values,g,sum_val);

         //预处理出来min_val数组
         dfs_min_val(0,-1,values,g,min_val);
         return sum_val[0] - min_val[0];
    }
};

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

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

相关文章

大漠插件的使用过程(一、插件的注册)

为何使用大漠插件 本人玩游戏时发现一些重复操作及其耗时&#xff0c;若使用识图、识字软件来制作脚本可节约大量时间。本来是选择了按键精灵来开发&#xff0c;但是由于按键精灵因为某些不知名原因导致无法识图成功&#xff0c;遂放弃按键精灵。同时早闻大漠插件的大名&#x…

任正非说:铁三角是利益统一体,就像拼刺刀一样一人管住120度角

你好&#xff01;这是华研荟【任正非说】系列的第31篇文章&#xff0c;让我们聆听任正非先生的真知灼见&#xff0c;学习华为的管理思想和管理理念。 一、代表处是综合性的直接作战组织&#xff0c;代表处以最小作战单位参战作战&#xff0c;这种就是精兵组织。代表处归代表管理…

12 款小众宝藏AI工具,90% 的开发者不了解

AI工具的发展一日千里&#xff0c;了解这些AI工具的功能以及它们如何提高开发过程中的效率和创新&#xff0c;变得尤为重要&#xff0c;这里分享了 12个宝藏的人工智能和低代码工具&#xff0c;希望对大家的工作与学习有所帮助。 1.Pieces for Developers 网址&#xff1a;ht…

FPGA配置采集AR0135工业相机,提供2套工程源码和技术支持

目录 1、前言免责声明 2、AR0135工业相机简介3、我这里已有的 FPGA 图像处理解决方案4、设计思路框架AR0135配置和采集图像缓存视频输出 5、vivado工程1–>Kintex7开发板工程6、vivado工程1–>Zynq7100开发板工程7、上板调试验证8、福利&#xff1a;工程代码的获取 1、前…

作用域,基本数据类型(常量const),转义字符,单引号与双引号,运算符

1.作用域 全局作用域&#xff1a;定义在所有花括号外的名字具有“全局作用域” 块作用域&#xff1a;在某个花括号内定义的名字具有“块作用域” 一般把具有全局作用域的变量叫做“全局变量”&#xff0c;具有块作用域的变量叫做“局部变量” 如果在嵌套作用域里出现重名&a…

网页视频录制技巧,解锁录制新体验

“网页视频怎么录制呀&#xff1f;在百度观看了一个视频&#xff0c;但是不能下载&#xff0c;朋友说可以录屏的方式保存下来&#xff0c;可是我不知道网页视频怎么录制&#xff0c;有人知道怎么操作吗&#xff0c;非常感谢&#xff01;” 在现代的教育、营销和协作环境中&…

App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法

根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》&#xff0c;相信不少要进行IOS平台App备案的朋友遇到了一个问题&#xff0c;就是apple不提供云管理式证书的下载&#xff0c;也就无法获取公钥及证书SHA-1指纹。 已经上架的应用不想重…

【EMD】1.初识经验模态分解EMD

/*** poject 经验模态分解及其衍生算法的研究及其在语音信号处理中的应用* author jUicE_g2R(qq:3406291309)* * language MATLAB/Python/C/C* EDA Base on matlabR2022b* editor Obsidian&#xff08;黑曜石笔记软件&#xff09;* * copyright 2023* …

全面采集商品数据的电商API接口对接【支持5大主流电商平台】

做小程序商城时&#xff0c;最崩溃的瞬间是什么&#xff1f; 一定是当你有几百件商品&#xff0c;却要一件一件编辑商品名称、规格、上传图片吧…… 为了帮助商家快速上货开店&#xff0c;我们可以接入电商API接口&#xff0c;方便商家一键采集淘宝、天猫、京东、拼多多、168…

AI短视频制作一本通:文本生成视频、图片生成视频、视频生成视频

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 第一部分&#xff1a;文…

UserAgent如何使用

UserAgent是HTTP请求头的一部分&#xff0c;用于标识发送请求的客户端应用程序或浏览器。在发送HTTP请求时&#xff0c;通常会在请求头中包含UserAgent信息&#xff0c;以便服务器能够识别请求的来源。 在使用OkHttpClient发送HTTP请求时&#xff0c;您可以通过以下方式设置Us…

虚拟课堂笔记

物理磁盘类型-SATA盘 SATA的全称是Serial Advanced Technology Attachment,SATA (Serial ATA)口的硬盘又叫串口硬盘。SATA采用串行连接方式&#xff0c;串行ATA总线使用嵌入式时钟信号&#xff0c;具备了更强的纠错能力&#xff0c;与以往相比其最大的区别在于能对传输指令(不…

盘点苹果手机导出照片到电脑的3个方法!

大家都知道&#xff0c;手机中的照片是非常占用空间的。特别是对喜欢拍照的女生来说&#xff0c;每一张照片都很珍贵&#xff0c;并且也不舍得删除&#xff0c;所以想要将照片导出到电脑上进行保存。这样&#xff0c;也方便以后进行恢复与查看。 对于想要将苹果手机上的照片导…

8 ICMP与ping

1、ICMP 协议的格式 一般在网络不同的时候&#xff0c;我们首先想到的是ping 那你知道 ping 是如何工作的吗&#xff1f; 1.ping 是基于 ICMP 协议工作的。 2.ICMP全称Internet Control Message Protocol&#xff0c;就是互联网控制报文协议。这里的关键在于"控制"…

大桌子初步使用

大桌子安装成功后进入应用市场首推安装首页和网盘 一键安装的时候如果出现这样的错误&#xff0c;只要你能保证服务器是正常联网的就再试一次&#xff0c;十有八九就是网络不稳定 安装成功后&#xff0c;要到已安装里去启用一下 然后回到这个页面 http://服务器ip/dzzoffice/h…

过去,并没有结束

你好&#xff0c;我是 EarlGrey&#xff0c;一名双语学习者&#xff0c;会一点编程。 目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。点击上方蓝字关注我&#xff0c;持续获取好书、高效工具分享&#xff0c;一起提升认知和思维。 从本期开始&#xff0c…

PHP运行代码示例

php <?php require_once curl.php; $proxy_host ; $proxy_port ; // 创建一个新的 cURL 会话 $ch curl_init(); // 设置 cURL 会话的信息 curl_setopt($ch, CURLOPT_PROXY, "$proxy_host:$proxy_port"); // 设置 cURL 会话的超时时间 curl_setopt($ch, CU…

太神奇了!办公大楼居然还能这么管理

随着现代社会的不断发展&#xff0c;火灾仍然是一种极具威胁性的灾害&#xff0c;对各种环境和行业都构成了潜在威胁。 因此&#xff0c;烟感监控系统的重要性愈加凸显&#xff0c;它不仅仅是一个安全装备&#xff0c;更是对人们生命安全和财产保护的承诺。 客户案例 工业生产…

树莓派上使用Nginx通过内网穿透实现无公网IP访问内网本地站点

前言 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Nginx 的内存占用率非常低&#xff0c;可以在树莓派等资源受限的设备上运行。同时结合c…

概率论和数理统计(一)概率的基本概念

前言 生活中对于事件的发生,可以概括为 确定现象&#xff1a;在一定条件下必然发生&#xff0c;如日出随机现象&#xff1a;在个别试验中其结果呈现出不确定性&#xff0c;在大量重复试验中其结果又具有统计规律的现象&#xff0c;称之为随机现象。 随机现象的特点&#xff…