分享 - 树形dp

树形 d p dp dp

例1 - 基础

链接:树上子链

练手

分析

  • 其实一看题就很显然的树形 d p dp dp
  • 子链在这里分为两种情况,如图黑链和红链在这里插入图片描述

思路

  • d p [ i ] dp[i] dp[i] 表示以 i i i 开头的红链的最大权值
  • 易得: d p [ i ] = m a x ( d p [ i ] , a [ u ] + d p [ v ] ) dp[i] = max(dp[i], a[u] + dp[v]) dp[i]=max(dp[i],a[u]+dp[v])
  • 黑链的更新你可以另设一个 d p dp dp ,也可以直接更新答案 a n s = m a x ( a n s , d p [ u ] + d p [ v ] ) ans = max(ans, dp[u] + dp[v]) ans=max(ans,dp[u]+dp[v])
  • 黑链存在的话一定是最长两条红链的和,应该说是两条子红链加父亲节点权值 你可以想想这样为什么行
#include <bits/stdc++.h>using ll = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int n;std::cin >> n;std::vector<ll> a(n + 1);for (int i = 1; i <= n; ++i) {std::cin >> a[i];}std::vector<std::pair<int ,int>> e((n + 1) << 1);std::vector<int> head(n + 1);int cnt = 0;auto add = [&](int u, int v) {e[++cnt] = {v, head[u]}, head[u] = cnt;};for (int i = 1; i < n; ++i) {int u, v;std::cin >> u >> v;add(u, v);add(v, u);}ll ans = -1e18;std::vector<ll> dp(n + 1);std::function<void(int, int)> dfs = [&](int u, int f) {dp[u] = a[u];for (int i = head[u]; i; i = e[i].second) {int v = e[i].first;if (v xor f) {dfs(v, u);ans = std::max(ans, dp[u] + dp[v]);dp[u] = std::max(dp[u], a[u] + dp[v]);}}ans = std::max(ans, dp[u]);};dfs(1, 0);std::cout << ans;return 0;
}

例2 - 进阶

链接:二叉苹果树

练手

分析

  • 树上背包

思路

  • d p [ i ] [ j ] dp[i][j] dp[i][j] 表示以 i i i 节点保留 j j j 条树枝最多苹果数量。
  • 易得: ∑ j = 2 m ∑ k = 1 , k < j s z [ v ] d p [ u ] [ j ] = m a x ( d p [ u ] [ j ] , d p [ u ] [ j − k ] + d p [ v ] [ k ] \sum\limits_{j=2}^m \sum\limits_{k=1,k<j}^{sz[v]}dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k] j=2mk=1,k<jsz[v]dp[u][j]=max(dp[u][j],dp[u][jk]+dp[v][k]
  • 注意:这里的二维其实相当于普通背包的一维,所以 j j j 的枚举应该倒序。
#include<bits/stdc++.h>using ll = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int n, q;std::cin >> n >> q;++q;std::vector<std::tuple<int, int, int>> e((n + 1) << 1);std::vector<int> head(n + 1);int cnt = 0;auto add = [&](int u, int v, int w) {e[++cnt] = {v, w, head[u]}, head[u] = cnt;};for (int i = 1; i < n; ++i) {int u, v, w;std::cin >> u >> v >> w;add(u, v, w);add(v, u, w);}std::vector<std::vector<int>> dp(n + 1, std::vector<int>(q + 1));std::vector<int> sz(n + 1);std::function<void(int, int, int)> dfs = [&](int u, int f, int m) {sz[u] = 1;for (int i = head[u]; i;) {auto [v, w, nxt] = e[i];if (f xor v) {dp[v][1] = w;dfs(v, u, m);sz[u] += sz[v];for (int j = m; j > 1; --j) {for (int k = 1; k <= sz[v] and k < j; ++k) {dp[u][j] = std::max(dp[u][j], dp[u][j - k] + dp[v][k]);}}}i = nxt;}};dfs(1, 0, q);std::cout << dp[1][q];return 0;
}

例3 - 困难

链接:树上染色

练手,这个更难

分析

  • 可以考虑上题一样就背包思想,枚举。

思路

  • d p [ u ] [ j ] dp[u][j] dp[u][j] u u u 节点 染 j j j 个为黑色最大效益。
  • 易得: ∑ j = 0 m i n ( k , s z [ u ] ) ∑ l = 0 m i n ( s z [ v ] , l ) d p [ u ] [ j ] = m a x ( d p [ u ] [ j ] , d p [ u ] [ j − l ] + d p [ v ] [ l ] + v a l \sum\limits_{j=0}^{min(k,sz[u])} \sum\limits_{l=0}^{min(sz[v],l)}dp[u][j] = max(dp[u][j], dp[u][j-l]+dp[v][l]+val j=0min(k,sz[u])l=0min(sz[v],l)dp[u][j]=max(dp[u][j],dp[u][jl]+dp[v][l]+val
  • v a l val val 即是很常见的计算贡献的思想。
  • 考虑一条边把树分成两部分树 A A A ,树 B B B ,树 B B B 选择 l l l 个点染黑色,那么另外 k − l k - l kl 个黑色节点即在树 A A A,那么这条边就会被计算 l × ( k − l ) l \times (k-l) l×(kl) 次,贡献即为 l × ( k − l ) × w l\times(k-l)\times w l×(kl)×w 。树 B B B 的另外 s z [ B ] − l sz[B]-l sz[B]l 个节点即为白色,那么另外 n − k − ( s z [ B ] − l ) n-k-(sz[B]-l) nk(sz[B]l) 个白色节点即在树 A A A ,所以该边白色贡献为 ( s z [ B ] − l ) × ( n − k − ( s z [ B ] − l ) ) ∗ w (sz[B] - l) \times (n - k - (sz[B] - l)) * w (sz[B]l)×(nk(sz[B]l))w
  • 同样倒序枚举 j j j
#include <bits/stdc++.h>using ll = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int n, k;std::cin >> n >> k;std::vector<std::tuple<int, ll, int>> e((n + 1) << 1);std::vector<int> head(n + 1);int cnt = 0;auto add = [&](int u, int v, ll w) {e[++cnt] = {v, w, head[u]}, head[u] = cnt;};for (int i = 1; i < n; ++i) {int u, v;ll w;std::cin >> u >> v >> w;add(u, v, w);add(v, u, w);}std::vector<std::vector<ll>> dp(n + 1, std::vector<ll>(k + 1, -1));std::vector<int> sz(n + 1);std::function<void(int, int)> dfs = [&](int u, int f) {sz[u] = 1;dp[u][0] = dp[u][1] = 0;for (int i = head[u]; i;) {auto [v, w, nxt] = e[i];if (v xor f) {dfs(v, u);sz[u] += sz[v];for (int j = std::min(k, sz[u]); j >= 0; --j) {for (int l = 0; l <= std::min(sz[v], k); ++l) {if (dp[u][j - l] not_eq -1 and j >= l) {ll val = 1ll * l * (k - l) * w + 1ll * (sz[v] - l) * (n - k - (sz[v] - l)) * w;dp[u][j] = std::max(dp[u][j], dp[u][j - l] + dp[v][l] + val);}}}}i = nxt;}};dfs(1, 0);std::cout << dp[1][k];return 0;
}

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

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

相关文章

祝贺!阿里云PolarDB斩获数据库国际顶会ICDE 2024工业赛道最佳论文

5月17日消息&#xff0c;在荷兰举行的国际顶级数据库学术会议ICDE 2024上&#xff0c;阿里云斩获工业和应用赛道的“最佳论文奖”&#xff0c;这也是中国企业首次获此殊荣。阿里云PolarDB创新性地解决了数据库Serverless中跨机事务迁移的核心难题&#xff0c;将跨机迁移时间压缩…

智能客服:论小红书商家杀出重围的正确姿势!

小红书「起飞」密码 洞悉需求&#xff0c;主动应变 面对众多的互联网平台&#xff0c;选择一个合适的平台宣传自家的品牌&#xff0c;也是一门学问&#xff0c;从“遇事不决&#xff0c;小红书”&#xff0c;这一 slogan 就能精准地捕捉了用户搜索行为的新趋势。 在过去的十…

【C++奇妙冒险】拷贝构造函数、运算符重载(赋值重载|const成员|取地址重载|const取地址重载)

文章目录 前言&#x1f6a9;拷贝构造函数&#x1fae7;概念&#x1fae7;特征&#x1fae7;默认生成的拷贝构造&#x1fae7;default关键字&#xff08;浅谈&#xff09; &#x1f6a9;运算符重载&#x1fae7;概念&#x1fae7;运算符重载注意事项&#x1fae7;封装如何保证&a…

如何使用GPT-4o?如何使用 GPT-4o API?

如何使用GPT-4o&#xff1f; GPT-4o 也可以通过 ChatGPT 界面使用 如何使用 GPT-4o API 新的 GPT-4o 模型遵循 OpenAI 现有的聊天完成 API&#xff0c;使其向后兼容且易于使用。 ​ 如何升级GPT4Plus&#xff1f; 升级ChatGPTPLSU4需要一张虚拟卡&#xff0c;点击获取​​​…

Java(六)——抽象类与接口

文章目录 抽象类和接口抽象类抽象类的概念抽象类的语法抽象类的特性抽象类的意义 接口接口的概念接口的语法接口的特性接口的使用实现多个接口接口与多态接口间的继承抽象类和接口的区别 抽象类和接口 抽象类 抽象类的概念 Java使用类实例化对象来描述现实生活中的实体&…

【第一节】从C语言到C++

目录 一、面向对象编程 1.早期概念 2.发展与普及 3. 现代发展 二、从C语言到C 1.关于堆内存的使用 2.关于函数重载 3.关于默认参数 4.引用 5.引用参数 6.作用域符号 三、C的输入输出机制 一、面向对象编程 面向对象编程&#xff08;Object-Oriented Programming&am…

如何进一步缩短Python性能

1、问题背景 给定一个(x,y)处的节点网格&#xff0c;每个节点有一个值(0…255)从0开始。有N个输入坐标&#xff0c;每个坐标在(0…x, 0…y)的范围内。一个值Z&#xff0c;它定义了节点的“邻域”。增加输入坐标及其邻居节点的值。网格边缘之外的邻居被忽略。基准案例&#xff…

产教协同|暴雨AI算力赋能传媒实践教学

近日&#xff0c;“第七届传媒实践教学创新研讨会暨中国高校影视学会实验教学专业委员会年会”在美丽的山城重庆成功举办。本次大会以“拥抱AI&#xff0c;融合共生”为主题&#xff0c;吸引了来自全国200多所高校、30多家企业以及700多位大视听实践教学产学研用各界专家、学者…

Data Lakehouse:你的下一个数据仓库

作者&#xff1a;张友东 StarRocks TSC member/镜舟科技 CTO 数据分析是现代企业和组织决策过程中不可或缺的一部分&#xff0c;数据分析技术经过数十年的发展&#xff0c;需求场景从 BI 报表到数据探寻、实时预测、用户画像等不断丰富&#xff0c;技术架构经历从数据仓库、数据…

【AIGC】GPT-4o技术分析-浅谈

GPT-4o&#xff1a;人工智能技术的全新里程碑 一、引言二、GPT系列版本间的对比分析三、GPT-4o的技术能力分析多模态处理能力速度与性能优化情感理解与表达能力 四、个人整体感受五、结语 一、引言 在人工智能技术的浪潮中&#xff0c;OpenAI再次以其卓越的创新能力引领潮流。近…

15.Redis之持久化

0.知识引入 mysql的事务,有四个比较核心的特性. 1. 原子性 2.一致性 3.持久性 >(和持久化说的是一回事)【把数据存储在硬盘 >持久把数据存储茌内存上>不持久~】【重启进程/重启主机 之后,数据是否存在!!】 4.隔离性~ Redis 是一个 内存 数据库.把数据存储在内存中的…

RFID芯片掼蛋牌:高科技与传统玩法结合,游戏体验焕然一新。

火爆“出圈”的掼蛋&#xff0c;是一种玩法相当鲜明的智力游戏。近年来得到了不少的推广和发展&#xff0c;各地举办了各种掼蛋比赛和活动&#xff0c;吸引了大量的参赛者和观众。此外&#xff0c;一些企业和机构也开始将掼蛋作为一种企业文化或者社交活动的方式&#xff0c;通…

灯下黑”挖出国内知名安全平台某BUF的CSRF漏洞

漏洞复现&#xff1a; 漏洞点在删除文章的地方&#xff0c;首先为了测试先发布一篇文章 发布之后我们可以查看文章&#xff0c;注意url中的一串数字&#xff0c;就是这篇文章的id&#xff0c;如下如&#xff1a; 这里的文章id是“271825”&#xff0c;首先抓一下删除文章的数据…

JavaScript基础(十)

上一篇学了各种数组方法&#xff0c;正好先做个练习回忆一下: 排序并去重 我随便写一组数&#xff0c;要求排好并去掉重复的: var arr [2,8,1,7,2,6,1,5,2,7,6,5]; for (var i0; i<arr.length; i){ for (var ji1; j<arr.length; j){ if(arr[i]arr[j]){ arr.splice(j,1)…

LeetCode 474.一和零

没做出来&#xff0c;最后看了解析&#xff0c;看了半天才懂。 我一开始把这个题当成多重背包来做了&#xff0c;因为有0和1两个参数需要考虑&#xff0c;但是中间很多情况不知道怎么处理。后面看了解析才知道这是个01背包问题&#xff0c;0和1都是一个物品上的属性&#xff0c…

K-means 聚类模型详解

K-means 聚类模型详解 K-means 是一种常用的无监督学习算法&#xff0c;用于将数据集分成 K 个簇。其目标是最小化各个簇内数据点到簇中心的距离平方和。K-means 广泛应用于图像压缩、市场细分、模式识别等领域。 算法步骤 初始化: 随机选择 K 个初始簇中心&#xff08;质心…

【主题广泛|投稿优惠】2024年区块链、网络与物联网国际会议(BNIT 2024)

2024年区块链、网络与物联网国际会议&#xff08;BNIT 2024&#xff09; 2024 International Conference on Blockchain, Networks, and the Internet of Things 【重要信息】 大会地点&#xff1a;深圳 大会官网&#xff1a;http://www.icbnit.com 投稿邮箱&#xff1a;icbni…

揭秘智慧校园:可视化技术引领教育新篇章

随着科技的飞速发展&#xff0c;我们的生活方式正在经历一场前所未有的变革。而在这场变革中&#xff0c;学校作为培养未来人才的重要基地&#xff0c;也在不断地探索与创新。 一、什么是校园可视化&#xff1f; 校园可视化&#xff0c;就是通过先进的信息技术&#xff0c;将学…

永久免费SSL证书领取流程

一、SSL证书的前世今生 起源&#xff1a; SSL证书起源于1994年&#xff0c;当时网景公司&#xff08;Netscape&#xff09;推出了安全套接字层&#xff08;SSL&#xff0c;Secure Sockets Layer&#xff09;协议&#xff0c;这是一种加密通信协议&#xff0c;用于在客户端和服…

武汉城投城更公司与竹云科技签署战略协议,携手构建智慧城市新未来!

2024年5月16日&#xff0c;武汉城投城更公司与深圳竹云科技股份有限公司&#xff08;以下简称“竹云”&#xff09;签订战略合作协议&#xff0c;双方将深入推进产业项目合作。 签约现场&#xff0c;双方围绕产业项目合作方向、路径和内容等进行了全面深入交流。城投城更公司党…