力扣 第 125 场双周赛 解题报告 | 珂学家 | 树形DP + 组合数学


前言

image.png


整体评价

T4感觉有简单的方法,无奈树形DP一条路上走到黑了,这场还是有难度的。


T1. 超过阈值的最少操作数 I

思路: 模拟

class Solution {public int minOperations(int[] nums, int k) {return (int)Arrays.stream(nums).filter(x -> x < k).count();}
}

T2. 超过阈值的最少操作数 II

思路: 模拟

按题意模拟即可,需要注意int溢出问题就行。

class Solution {public int minOperations(int[] nums, int k) {PriorityQueue<Long> pq = new PriorityQueue<>();for (long num : nums) {pq.offer(num);}int ans = 0;while (pq.peek() < k) {long x = pq.poll(), y = pq.poll();pq.offer(Math.min(x, y) * 2 + Math.max(x, y));ans++;}return ans;}
}

T3. 在带权树网络中统计可连接服务器对数目

思路: 枚举 + dfs/bfs + 组合数学

因为树的点数n( n ≤ 1000 n\le1000 n1000), 所以枚举点,从该点进行dfs/bfs,然后对每个分支进行组合统计。

组合统计的核心

点 u 出发的各个分支满足整除的数,组合序列为 c 0 , c 1 , c 2 , c 3 , . . . , c m 点u出发的各个分支满足整除的数,组合序列为 c_0, c_1, c_2, c_3, ..., c_m u出发的各个分支满足整除的数,组合序列为c0,c1,c2,c3,...,cm

其 s = ∑ i = 0 i = m c i 其 s = \sum_{i=0}^{i=m} c_i s=i=0i=mci

结果为 r e s [ u ] = ( ∑ i = 0 i = m c i ∗ ( s − c i ) ) / 2 结果为 res[u] = (\sum_{i=0}^{i=m} c_i * (s - c_i)) / 2 结果为res[u]=(i=0i=mci(sci))/2

这样时间复杂度为 O ( n 2 ) O(n^2) O(n2), 是可以接受的。

class Solution {List<int[]> []g;int signalSpeed;// fa是阻断点int bfs(int u, int w, int fa) {int res = 0;boolean[] vis = new boolean[g.length];Deque<int[]> deq = new ArrayDeque<>();vis[u] = true;deq.offer(new int[] {u, w});if (w % signalSpeed == 0) {res ++;}while (!deq.isEmpty()) {int[] cur = deq.poll();int p = cur[0];int v = cur[1];for (int[] e: g[p]) {if (e[0] == fa) continue;if (vis[e[0]]) continue;if ((v + e[1]) % signalSpeed == 0) res++;deq.offer(new int[] {e[0], v + e[1]});vis[e[0]] = true;}}return res;}public int[] countPairsOfConnectableServers(int[][] edges, int signalSpeed) {int n = edges.length + 1;g = new List[n];Arrays.setAll(g, x->new ArrayList<>());this.signalSpeed = signalSpeed;for (int[] e: edges) {g[e[0]].add(new int[] {e[1], e[2]});g[e[1]].add(new int[] {e[0], e[2]});}int[] res = new int[n];for (int i = 0; i < n; i++) {int sum = 0;List<Integer> lists = new ArrayList<>();for (int[] e: g[i]) {int tmp = bfs(e[0], e[1], i);lists.add(tmp);sum += tmp;}int tot = 0;for (int j = 0; j < lists.size(); j++) {tot += lists.get(j) * (sum - lists.get(j));}res[i] = tot / 2;}return res;}}

如果该题把n变成 n ≤ 1 0 5 n\le10^5 n105, 那该如何解呢?

感觉换根 D P 可行,但是需要限制 s i g n a l S p e e d 范围在 100 之内 , 这样可控制在 O ( 1 0 7 ) 感觉换根DP可行,但是需要限制 signalSpeed 范围在100之内, 这样可控制在O(10^7) 感觉换根DP可行,但是需要限制signalSpeed范围在100之内,这样可控制在O(107)

如果signalSpeed很大,感觉没辙啊。


T4. 最大节点价值之和

思路: 树形DP

树形DP的解法更加具有通用性,所以比赛就沿着这个思路写。

如果操作不是异或,那这个思路就更有意义 如果操作不是异或,那这个思路就更有意义 如果操作不是异或,那这个思路就更有意义

对于任意点u, 其具备两个状态。

d p [ u ] [ 0 ] , d p [ u ] [ 1 ] , 表示参与和没有参与异或下的以 u 为根节点的子树最大和。 dp[u][0], dp[u][1], 表示参与和没有参与异或下的以u为根节点的子树最大和。 dp[u][0],dp[u][1],表示参与和没有参与异或下的以u为根节点的子树最大和。

那么其转移方程,其体现在当前节点u和其子节点集合S( v ∈ u 的子节点 v\in u的子节点 vu的子节点)的迭代递推转移。

class Solution {int k;int[] nums;List<Integer>[]g;long[][] dp;void dfs(int u, int fa) {// 该节点没参与, 该节点参与了long r0 = nums[u], r1 = Long.MIN_VALUE / 10;for (int v: g[u]) {if (v == fa) continue;dfs(v, u);long uRev0 = r0 + (nums[u]^k) - nums[u];long uRev1 = r1 - (nums[u]^k) + nums[u];long vRev0 = dp[v][0] + (nums[v]^k) - nums[v];long vRev1 = dp[v][1] - (nums[v]^k) + nums[v];long x0 = Math.max(r0 + Math.max(dp[v][0], dp[v][1]),Math.max(uRev1 + vRev1, uRev1 + vRev0));long x1 = Math.max(r1 + Math.max(dp[v][1], dp[v][0]),Math.max(uRev0 + vRev0, uRev0 + vRev1));r0 = x0;r1 = x1;}dp[u][0] = r0;dp[u][1] = r1;}public long maximumValueSum(int[] nums, int k, int[][] edges) {int n = nums.length;this.g = new List[n];this.nums = nums;this.k = k;this.dp = new long[n][2];Arrays.setAll(g, x -> new ArrayList<>());for (int[] e: edges) {g[e[0]].add(e[1]);g[e[1]].add(e[0]);}dfs(0, -1);return Math.max(dp[0][0], dp[0][1]);}
}
class Solution:def maximumValueSum(self, nums: List[int], k: int, edges: List[List[int]]) -> int:n = len(nums)g = [[] for _ in range(n)]for e in edges:g[e[0]].append(e[1])g[e[1]].append(e[0])dp = [[0] * 2 for _ in range(n)]def dfs(u, fa):r0, r1 = nums[u], -0x3f3f3f3f3ffor v in g[u]:if v == fa:continuedfs(v, u)uRev0 = r0 + (nums[u]^k) - nums[u];uRev1 = r1 - (nums[u]^k) + nums[u];vRev0 = dp[v][0] + (nums[v]^k) - nums[v];vRev1 = dp[v][1] - (nums[v]^k) + nums[v];t0 = max(r0 + max(dp[v][0], dp[v][1]), max(uRev1 + vRev0, uRev1 + vRev1))t1 = max(r1 + max(dp[v][0], dp[v][1]), max(uRev0 + vRev0, uRev0 + vRev1))r0, r1 = t0, t1dp[u][0], dp[u][1] = r0, r1dfs(0, -1)return max(dp[0][0], dp[0][1])

由于异或的特点,所以这题可以抛弃边的束缚。

任意两点 u , v ,可以简单构造一条路径,只有端点 ( u , v ) 出现 1 次,其他点都出现 2 次 任意两点u,v,可以简单构造一条路径,只有端点(u,v)出现1次,其他点都出现2次 任意两点u,v,可以简单构造一条路径,只有端点(u,v)出现1次,其他点都出现2

异或涉及边的两点,因此异或的点必然是偶数个,这是唯一的限制.

class Solution {public long maximumValueSum(int[] nums, int k, int[][] edges) {long sum = 0;PriorityQueue<Long> pq = new PriorityQueue<>(Comparator.comparing(x -> -x));for (int v: nums) {pq.offer((long)(v ^ k) - v);sum += v;}while (pq.size() >= 2) {long t1 = pq.poll();long t2 = pq.poll();if (t1 + t2 > 0) {sum += t1 + t2;} else {break;}}return sum;}
}
class Solution:def maximumValueSum(self, nums: List[int], k: int, edges: List[List[int]]) -> int:s = sum(nums)arr = [(v ^ k) - v for v in nums]arr.sort(key=lambda x: -x)n = len(nums)for i in range(0, n, 2):if i + 1 < n and arr[i] + arr[i + 1] > 0:s += arr[i] + arr[i + 1]return s

写在最后

image.png

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

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

相关文章

VM虚拟机无法传输文件(更新时间24/3/3)

出现这个问题一般是未安装VMware Tools 以下为手动安装教程及可能出现的问题的解决方法&#xff1a; 1. 准备安装 2.用cmd手动启动安装 3. 安装过程默认即可&#xff0c;直接一直下一步 4.安装完成后会自动重启虚拟机&#xff08;没有的话手动重启即可&#xff09; 5.重启以后…

StarCoder2模型,释放你的大模型编码潜能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

部署若依前后端分离项目,连接数据库失败

部署若依前后端分离项目&#xff0c;连接数据库失败&#xff0c;异常如下&#xff1a; 解决方案&#xff1a;application配置文件里&#xff0c;连接数据库的参数useSSL的值改为false

leetcode 长度最小的子数组

在本题中&#xff0c;我们可以知道&#xff0c;是要求数组中组成和为target的最小子数组的长度。所以&#xff0c;我们肯定可以想到用两层for循环进行遍历&#xff0c;然后枚举所有的结果进行挑选&#xff0c;但这样时间复杂度过高。 我们可以采用滑动窗口&#xff0c;其实就是…

编写dockerfile挂载卷、数据容器卷

编写dockerfile挂载卷 编写dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…

2024 年广东省职业院校技能大赛(高职组)“云计算应用”赛项样题 2

#需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企业根据自身业务需求&#…

每日OJ题_牛客_合法括号序列判断

目录 合法括号序列判断 解析代码 合法括号序列判断 合法括号序列判断__牛客网 解析代码 class Parenthesis {public:bool chkParenthesis(string A, int n){if (n & 1) // 如果n是奇数return false;stack<char> st;for (int i 0; i < n; i) {if (A[i] () {s…

笔记本hp6930p安装Android-x86补记

在上一篇日记中&#xff08;笔记本hp6930p安装Android-x86避坑日记-CSDN博客&#xff09;提到hp6930p安装Android-x86-9.0&#xff0c;无法正常启动&#xff0c;本文对此再做尝试&#xff0c;原因是&#xff1a;Android-x86-9.0不支持无线网卡&#xff0c;需要在BIOS中关闭WLAN…

B082-SpringCloud-Eureka

目录 微服务架构与springcloud架构演变为什么使用微服务微服务的通讯方式架构的选择springcloud概述场景模拟之基础架构的搭建模拟微服务之间的服务调用目前远程调用的问题 eureka注册中心的作用注册中心的实现服务提供者注册到注册中心 springcloud基于springboot 微服务架构与…

10 计算机结构

冯诺依曼体系结构 冯诺依曼体系结构&#xff0c;也被称为普林斯顿结构&#xff0c;是一种计算机架构&#xff0c;其核心特点包括将程序指令存储和数据存储合并在一起的存储器结构&#xff0c;程序指令和数据的宽度相同&#xff0c;通常都是16位或32位 我们常见的计算机,笔记本…

在Centos7中用Docker部署gitlab-ce

一、介绍 GitLab Community Edition (GitLab CE) 是一个开源的版本控制系统和协作平台&#xff0c;用于管理和追踪软件开发项目。它提供了一套完整的工具和功能&#xff0c;包括代码托管、版本控制、问题跟踪、持续集成、持续交付和协作功能&#xff0c;使团队能够更加高效地进…

动态规划|【路径问题】|931.下降路径最小和

目录 题目 题目解析 思路 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 代码 题目 931. 下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开…

【Vue3】Props的使用详解

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

概率基础——多元正态分布

概率基础——多元正态分布 介绍 多元正态分布是统计学中一种重要的多维概率分布&#xff0c;描述了多个随机变量的联合分布。在多元正态分布中&#xff0c;每个随机变量都服从正态分布&#xff0c;且不同随机变量之间可能存在相关性。本文将以二元标准正态分布为例&#xff0…

多线程JUC 第2季 中断线程

一 中断线程 1.1 中断概念 1.在java中&#xff0c;没有提供一种立即停止一条线程。但却给了停止线程的协商机制-中断。 中断是一种协商机制。中断的过程完全需要程序员自己实现。也即&#xff0c;如果要中断一个线程&#xff0c;你需要手动调用该线程的interrupt()方法&…

录制用户操作实现自动化任务

先上视频&#xff01;&#xff01; 流程自动化工具-录制操作绘制流程 这个想法之前就有了&#xff0c;趁着周末时间给它撸出来。 实现思路 从之前的文章自动化桌面未来展望中已经验证了录制绘制流程图的可行性。基于DOM录制页面操作轨迹的思路监听页面点击、输入事件即可&…

无人机镜头稳定的原理和相关算法

无人机的镜头稳定主要基于两个关键技术&#xff1a;镜头平衡技术和实时电子稳像。无人机镜头稳定的原理和相关算法主要是通过镜头平衡技术和实时电子稳像技术来保持摄像镜头的稳定性&#xff0c;从而拍摄出清晰、稳定的画面。无人机镜头稳定的原理主要是通过传感器和算法来实现…

Ocr之PaddleOcr模型训练

目录 一、系统环境 1 镜像拉取ppocr 进行部署 2 安装paddlepaddle 二、训练前的准备 1 下载源码 2 预模型下载 3 修改模型训练文件yml 4 编排训练集 5 执行脚本进行训练 6 需要修改文件夹名称 三、开始训练 1 执行训练命令 2 对第一次评估进行解释 3 引言 五、总…

NestJS使用模板引擎ejs

模板引擎​ 模板引擎是一种用于生成动态内容的工具&#xff0c;它通过将预定义的模板与特定数据结合&#xff0c;来生成最终的输出。​ 在NodeJS开发中&#xff0c;我们会使用模板引擎来渲染一些常用的页面&#xff0c;比如渲染代表404的Not Found 页面&#xff0c;502的Bad …

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…