周赛370(模拟、树形DP(正难则反)、树状数组优化DP)

news2024/11/24 13:33:35

文章目录

  • 周赛370
    • [2923. 找到冠军 I](https://leetcode.cn/problems/find-champion-i/)
      • 模拟
    • [2924. 找到冠军 II](https://leetcode.cn/problems/find-champion-ii/)
      • 统计入度
    • [2925. 在树上执行操作以后得到的最大分数](https://leetcode.cn/problems/maximum-score-after-applying-operations-on-a-tree/)
      • 正难则反 + 树形DP
    • [2926. 平衡子序列的最大和](https://leetcode.cn/problems/maximum-balanced-subsequence-sum/)
      • 树状数组优化DP

周赛370

2923. 找到冠军 I

简单

一场比赛中共有 n 支队伍,按从 0n - 1 编号。

给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 <= i, j <= n - 1i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j ;否则,j 队比 i

在这场比赛中,如果不存在某支强于 a 队的队伍,则认为 a 队将会是 冠军

返回这场比赛中将会成为冠军的队伍。

示例 1:

输入:grid = [[0,1],[0,0]]
输出:0
解释:比赛中有两支队伍。
grid[0][1] == 1 表示 0 队比 1 队强。所以 0 队是冠军。

示例 2:

输入:grid = [[0,0,1],[1,0,1],[0,0,0]]
输出:1
解释:比赛中有三支队伍。
grid[1][0] == 1 表示 1 队比 0 队强。
grid[1][2] == 1 表示 1 队比 2 队强。
所以 1 队是冠军。

提示:

  • n == grid.length
  • n == grid[i].length
  • 2 <= n <= 100
  • grid[i][j] 的值为 01
  • 对于满足 i != j 的所有 i, jgrid[i][j] != grid[j][i] 均成立
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

模拟

class Solution {
    /**
    本质是某一行 i 除了 g[i][i] 其他都为 1
    */
    public int findChampion(int[][] grid) {
        int n = grid.length;
        for(int i = 0; i < n; i++){
            boolean winner = true;
            for(int j = 0; j < n; j++){
                if(i == j) continue;
                if(grid[i][j] == 0){
                    winner = false;
                    break;
                }
            }
            if(winner) return i;
        }
        return -1;
    }
}

2924. 找到冠军 II

中等

一场比赛中共有 n 支队伍,按从 0n - 1 编号。每支队伍也是 有向无环图(DAG) 上的一个节点。

给你一个整数 n 和一个下标从 0 开始、长度为 m 的二维整数数组 edges 表示这个有向无环图,其中 edges[i] = [ui, vi] 表示图中存在一条从 ui 队到 vi 队的有向边。

a 队到 b 队的有向边意味着 a 队比 b ,也就是 b 队比 a

在这场比赛中,如果不存在某支强于 a 队的队伍,则认为 a 队将会是 冠军

如果这场比赛存在 唯一 一个冠军,则返回将会成为冠军的队伍。否则,返回 -1

注意

  • 是形如 a1, a2, ..., an, an+1 的一个序列,且满足:节点 a1 与节点 an+1 是同一个节点;节点 a1, a2, ..., an 互不相同;对于范围 [1, n] 中的每个 i ,均存在一条从节点 ai 到节点 ai+1 的有向边。
  • 有向无环图 是不存在任何环的有向图。

示例 1:

img

输入:n = 3, edges = [[0,1],[1,2]]
输出:0
解释:1 队比 0 队弱。2 队比 1 队弱。所以冠军是 0 队。

示例 2:

img

输入:n = 4, edges = [[0,2],[1,3],[1,2]]
输出:-1
解释:2 队比 0 队和 1 队弱。3 队比 1 队弱。但是 1 队和 0 队之间不存在强弱对比。所以答案是 -1 。

提示:

  • 1 <= n <= 100
  • m == edges.length
  • 0 <= m <= n * (n - 1) / 2
  • edges[i].length == 2
  • 0 <= edge[i][j] <= n - 1
  • edges[i][0] != edges[i][1]
  • 生成的输入满足:如果 a 队比 b 队强,就不存在 b 队比 a 队强
  • 生成的输入满足:如果 a 队比 b 队强,b 队比 c 队强,那么 a 队比 c 队强

统计入度

class Solution {
    public int findChampion(int n, int[][] edges) {
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        int[] deg = new int[n];
        for(int[] e : edges){
            int x = e[0], y = e[1];
            g[x].add(y);
            deg[y] += 1;
        }
        int res = -1, cnt = 0;
        for(int i = 0; i < n; i++){
            if(deg[i] == 0){
                cnt += 1;
                res = i;
            }
        }
        return cnt == 1 ? res : -1;
    }
}

2925. 在树上执行操作以后得到的最大分数

中等

有一棵 n 个节点的无向树,节点编号为 0n - 1 ,根节点编号为 0 。给你一个长度为 n - 1 的二维整数数组 edges 表示这棵树,其中 edges[i] = [ai, bi] 表示树中节点 aibi 有一条边。

同时给你一个长度为 n 下标从 0 开始的整数数组 values ,其中 values[i] 表示第 i 个节点的值。

一开始你的分数为 0 ,每次操作中,你将执行:

  • 选择节点 i
  • values[i] 加入你的分数。
  • values[i] 变为 0

如果从根节点出发,到任意叶子节点经过的路径上的节点值之和都不等于 0 ,那么我们称这棵树是 健康的

你可以对这棵树执行任意次操作,但要求执行完所有操作以后树是 健康的 ,请你返回你可以获得的 最大分数

示例 1:

img

输入:edges = [[0,1],[0,2],[0,3],[2,4],[4,5]], values = [5,2,5,2,1,1]
输出:11
解释:我们可以选择节点 1 ,2 ,3 ,4 和 5 。根节点的值是非 0 的。所以从根出发到任意叶子节点路径上节点值之和都不为 0 。所以树是健康的。你的得分之和为 values[1] + values[2] + values[3] + values[4] + values[5] = 11 。
11 是你对树执行任意次操作以后可以获得的最大得分之和。

示例 2:

img

输入:edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values = [20,10,9,7,4,3,5]
输出:40
解释:我们选择节点 0 ,2 ,3 和 4 。
- 从 0 到 4 的节点值之和为 10 。
- 从 0 到 3 的节点值之和为 10 。
- 从 0 到 5 的节点值之和为 3 。
- 从 0 到 6 的节点值之和为 5 。
所以树是健康的。你的得分之和为 values[0] + values[2] + values[3] + values[4] = 40 。
40 是你对树执行任意次操作以后可以获得的最大得分之和。

提示:

  • 2 <= n <= 2 * 104
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • values.length == n
  • 1 <= values[i] <= 109
  • 输入保证 edges 构成一棵合法的树。

正难则反 + 树形DP

https://leetcode.cn/problems/maximum-score-after-applying-operations-on-a-tree/solutions/2513101/shu-xing-dpxuan-huo-bu-xuan-pythonjavacg-7aj6/

class Solution {
    /**
    正难则反,先把所有数都选上,加入到答案中,然后考虑不选哪些点权

    对于一棵以 x 的根的子树,如果这棵树是健康的,损失的最小分数是多少

    选或不选
    不选 损失根节点的情况下,损失的最小分数 = values[x]
    选   不损失根节点(根节点加到答案种) = sum(dfs(y))
    两种情况去最小值
     */
    public long maximumScoreAfterOperations(int[][] edges, int[] values) {
        List<Integer>[] g = new ArrayList[values.length];
        Arrays.setAll(g, e -> new ArrayList<>());
        g[0].add(-1); // 避免误把根节点当成叶子
        for(int[] e : edges){
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        // 先把所有分数加入答案
        long ans = 0;
        for(int v : values) ans += v;
        return ans - dfs(0, -1, g, values);

    }

    // dfs(x) 计算以 x 为根的子树是健康时,失去的最小分数
    public long dfs(int x, int fa, List<Integer>[] g, int[] values){
        if(g[x].size() == 1){ // x 是叶子
            return values[x];
        }
        long loss = 0; // 第二种情况
        for(int y : g[x]){
            if(y != fa){
                loss += dfs(y, x, g, values);
            }
        }
        return Math.min(values[x], loss); // 两种情况取最小值
    }
}

2926. 平衡子序列的最大和

困难

给你一个下标从 0 开始的整数数组 nums

nums 一个长度为 k子序列 指的是选出 k下标 i0 < i1 < ... < ik-1 ,如果这个子序列满足以下条件,我们说它是 平衡的

  • 对于范围 [1, k - 1] 内的所有 jnums[ij] - nums[ij-1] >= ij - ij-1 都成立。

nums 长度为 1子序列 是平衡的。

请你返回一个整数,表示 nums 平衡 子序列里面的 最大元素和

一个数组的 子序列 指的是从原数组中删除一些元素(也可能一个元素也不删除)后,剩余元素保持相对顺序得到的 非空 新数组。

示例 1:

输入:nums = [3,3,5,6]
输出:14
解释:这个例子中,选择子序列 [3,5,6] ,下标为 0 ,2 和 3 的元素被选中。
nums[2] - nums[0] >= 2 - 0 。
nums[3] - nums[2] >= 3 - 2 。
所以,这是一个平衡子序列,且它的和是所有平衡子序列里最大的。
包含下标 1 ,2 和 3 的子序列也是一个平衡的子序列。
最大平衡子序列和为 14 。

示例 2:

输入:nums = [5,-1,-3,8]
输出:13
解释:这个例子中,选择子序列 [5,8] ,下标为 0 和 3 的元素被选中。
nums[3] - nums[0] >= 3 - 0 。
所以,这是一个平衡子序列,且它的和是所有平衡子序列里最大的。
最大平衡子序列和为 13 。

示例 3:

输入:nums = [-2,-1]
输出:-1
解释:这个例子中,选择子序列 [-1] 。
这是一个平衡子序列,而且它的和是 nums 所有平衡子序列里最大的。

提示:

  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109

树状数组优化DP

https://leetcode.cn/problems/maximum-balanced-subsequence-sum/solutions/2513121/shu-zhuang-shu-zu-you-hua-dp-by-endlessc-3zf4/

class Solution {
    /**
    思考过程
    nums[ij] - nums[ij-1] >= ij - ij-1
    nums[i] - nums[j] >= i - j
    ==> nums[i] - i >= nums[j] - j
    定义 b[i] = nums[i] - i
    b[i] >= b[j]  
    ==> 从 b 中选一个子序列,满足这个子序列是一个非递减的序列
    求对应的元素和的最大值
    a 3 3 5 6
    b 3 2 4 3

    定义 f[i] = 以下标 i 结尾的子序列,对应的 nums 的元素和的最大值
    转移 f[i] = f[j] + nums[i], j < i && b[j] <= b[i]

    使用值域树状数组优化,用来维护前缀最大值,设下标为x=b[i],维护的值为max(f[x], f[x-1], f[x-2]..)
    实现时,需要先把nums[i] - i离散化
     */
    public long maxBalancedSubsequenceSum(int[] nums) {
        int n = nums.length;
        int[] b = new int[n];
        for(int i = 0; i < n; i++){
            b[i] = nums[i] - i;
        }
        Arrays.sort(b);

        BIT t = new BIT(b.length+1);
        for(int i = 0; i < n; i++){
            // j 为 nums[i]-i 离散化后的值(从 1 开始)
            int j = Arrays.binarySearch(b, nums[i] - i) + 1;
            long f = Math.max(t.preMax(j), 0) + nums[i];
            t.update(j, f);
        }
        return t.preMax(b.length);
    }
}

// 树状数组模板(维护前缀最大值)
class BIT {
    private long[] tree;

    public BIT(int n) {
        tree = new long[n];
        Arrays.fill(tree, Long.MIN_VALUE);
    }

    public void update(int i, long val) {
        while (i < tree.length) {
            tree[i] = Math.max(tree[i], val);
            i += i & -i;
        }
    }

    public long preMax(int i) {
        long res = Long.MIN_VALUE;
        while (i > 0) {
            res = Math.max(res, tree[i]);
            i &= i - 1;
        }
        return res;
    }
}

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

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

相关文章

用友NC及NC Cloud mxservlet反序列化漏洞复现

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具&#xff0c;用友NC提供了一系列业务管理模块&#xff0c;包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等&#xff0c;帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友NC及N…

小红书x-s、x-s-common算法研究与分析(仅供学习)

文章目录 1. 写在前面2. 参数分析2.1. x-s、x-t、x-s-common 1. 写在前面 最近花时间分析了一下xhs&#xff0c;研究的不深&#xff0c;也参考了网上许多开源出来的案例。简单记录一下&#xff0c;感兴趣的将就看一下吧&#xff01; 之前也研究过一段时间的某音&#xff0c;下…

VUE基础的一些总结

首先推荐观看VUE官方文档 目录 创建一个 Vue 应用 要创建一个 Vue 应用&#xff0c;你需要按照以下步骤操作&#xff1a; 步骤 1&#xff1a;安装 Node.js 和 npm 确保你的计算机上已经安装了 Node.js。你可以在 Node.js 官网 上下载并安装它。安装完成后&#xff0c;npm&…

io+day8

#ifndef __SEM2 #define __SEM3 4 //声明一个创>5 int init_sem(6 7 //声明一个p操8 int P(int sem9 10 //声明一个v操11 int W(int sem12 13 //声明一个删>14 int del_sem(i15 16 #endif 1 #include <myhead.h> …

【Python 千题 —— 基础篇】列表的最大值与最小值(for 循环版)

题目描述 题目描述 输出列表的最大值与最小值。题中有一个包含数字的列表 [11, 39, 100, 48, 392, 10, 9]&#xff0c;使用 for 循环输出这个列表的最大值与最小值。 输入描述 无输入。 输出描述 输出列表的最大值与最小值。 示例 示例 ① 输出&#xff1a; 列表的最…

【GitLab】-HTTP 500 curl 22 The requested URL returned error: 500~SSH解决

写在前面 本文主要介绍通过SSH的方式拉取GitLab代码。 目录 写在前面一、场景描述二、具体步骤1.环境说明2.生成秘钥3.GitLab添加秘钥4.验证SSH方式4.更改原有HTTP方式为SSH 三、参考资料写在后面系列文章 一、场景描述 之前笔者是通过 HTTP Personal access token 的方式拉取…

Redis 配置文件信息中文翻译版

前言 Redis 配置文件信息中文翻译版&#xff0c;方便大家阅读和理解对应参数信息及配置参数信息 # Redis configuration file example# Note on units: when memory size is needed, it is possible to specify # it in the usual form of 1k 5GB 4M and so forth: # 注意:当…

Django模型层

模型层 与数据库相关的&#xff0c;用于定义数据模型和数据库表结构。 在Django应用程序中&#xff0c;模型层是数据库和应用程序之间的接口&#xff0c;它负责处理所有与数据库相关的操作&#xff0c;例如创建、读取、更新和删除记录。Django的模型层还提供了一些高级功能 首…

Mars3d的timeline与locationBar样式重合问题处理方案

前置代码&#xff1a;配置了map的mapOptions &#xff0c;增加了默认的时间轴与下侧状态栏控件 export const mapOptions function (option) { option.control { timeline: { zoom: false, enabled: false }, // 方式1&#xff1a;options中添加控件 ; zoom - 禁止缩放 anim…

浏览器存储(localStorage和sessionStorage)

我们知道 js 写的效果&#xff0c;每次刷新都是从新执行&#xff0c;是不存在记录操作的&#xff0c;主要是大部分的效果不需要这样的处理 (一个 tab 切换&#xff0c;焦点图肯定不需要记住运行到哪里&#xff0c;刷新从新开始就好了)&#xff01; 在 html5 之前&#xff0c;前…

Oracle-动态sql学习笔记,由易至难讲解七个例子

本文章的内容来源于对oracle课堂上讲的内容做出的笔记 静态sql和动态sql 静态sql&#xff1a; 静态 SQL 是在编译时写死的 SQL 语句&#xff0c;即在程序编写阶段&#xff0c;SQL 语句已经被固定下来。 特点&#xff1a; 1.预编译&#xff1a; SQL 语句在程序编译时就会被…

【刷题专栏—突破思维】142. 环形链表 II

前言&#xff1a;本篇博客将讲解三个OJ题&#xff0c;前两个作为铺垫&#xff0c;最后完成环形链表的节点的寻找 文章目录 一、160. 相交链表二、141. 环形链表三、142. 环形链表II 一、160. 相交链表 题目链接&#xff1a;LeetCode—相交链表 题目描述&#xff1a; 给你两个单…

【VSCode】Visual Studio Code 配置简体中文环境教程

介绍 Visual Studio Code&#xff08;简称 VS Code&#xff09;是一款轻量级的代码编辑器&#xff0c;它支持多种编程语言&#xff0c;并且具有丰富的功能和插件扩展。如果你更喜欢使用简体中文界面&#xff0c;那么本教程将向你展示如何在 VS Code 中配置简体中文环境。 步骤…

如何调整图片尺寸:简单实用的教程分享

报名事业编考试的时候&#xff0c;会发现上传照片时会提示图片大小尺寸应该为多少&#xff0c;如果不符合规定就无法提交报名&#xff0c;那么怎么才能修改图片大小呢&#xff1f;最简单的方法就是利用调整照片大小工具来对图片尺寸修改&#xff0c;本文分享一个在线图片处理工…

如何提高领导力?

提升领导力的关键一方面要有正确的自我认知&#xff0c;另一方面就是坚持去实践&#xff0c;没有速成可言&#xff0c;没人那个人天生就具备领导力&#xff0c;有些人我们看起来是具有领导力的&#xff0c;但这些表象的背后可能是家庭环境的潜移默化&#xff0c;也有可能是个人…

智能导诊系统:基于机器学习和自然语言处理技术,可快速推荐合适的科室和医生

智能导诊系统是一种基于人工智能技术的新型系统&#xff0c;它能够为医院提供患者服务和管理&#xff0c;提高医院的管理效率和服务水平。 技术架构&#xff1a;springbootredismybatis plusmysqlRocketMQ 以下是智能导诊系统的应用场景和功能特点&#xff1a; 应用场景 1.患…

一个项目进行测试的一些最基本环境

在一个项目开发到发布的整个过程中&#xff0c;会使用到很多个环境进行测试和运行项目。最基本的开发环境、测试环境、准生产环境、生成环境 一、开发环境 开发环境顾名思义就是我们程序猿自己把项目放到自己的电脑上&#xff0c;配置好以后&#xff0c;跑起来项目&#xff0…

深度学习100例-卷积神经网络(CNN)实现mnist手写数字识别 | 第1天

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3.归一化4.可视化5.调整图片格式 二、构建CNN网络模型三、编译模型四、训练模型五、预测六、知识点详解1. MNIST手写数字数据集介绍2. 神经网络程序说明3. 网…

计算机毕业设计 基于Vue的米家商城系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

解决Qt5.13.0无MySQL驱动问题

一、前言 由于Qt5.12.3是最后提供mysql数据库插件的版本&#xff0c;往后的版本需要自行编译对应的mysql数据库插件&#xff0c;官方安装包不再提供。使用高版本的Qt就需要自行编译mysql驱动。 若没有编译在QT中调用Qsqldatabase库连接mysql时&#xff0c;提示出现如下问题&a…