周赛369(位运算、分类讨论、记忆化搜索==>动态规划、树形DP)

news2025/4/15 5:22:14

文章目录

  • 周赛369
    • [2917. 找出数组中的 K-or 值](https://leetcode.cn/problems/find-the-k-or-of-an-array/)
      • 位运算模拟
    • [2918. 数组的最小相等和](https://leetcode.cn/problems/minimum-equal-sum-of-two-arrays-after-replacing-zeros/)
      • 分类讨论
    • [2919. 使数组变美的最小增量运算数](https://leetcode.cn/problems/minimum-increment-operations-to-make-array-beautiful/)
      • 记忆化搜索 ==> 动态规划
    • [2920. 收集所有金币可获得的最大积分](https://leetcode.cn/problems/maximum-points-after-collecting-coins-from-all-nodes/)
      • 树形DP

周赛369

2917. 找出数组中的 K-or 值

简单

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

nums 中的 K-or 是一个满足以下条件的非负整数:

  • 只有在 nums 中,至少存在 k 个元素的第 i 位值为 1 ,那么 K-or 中的第 i 位的值才是 1 。

返回 numsK-or 值。

注意 :对于整数 x ,如果 (2i AND x) == 2i ,则 x 中的第 i 位值为 1 ,其中 AND 为按位与运算符。

示例 1:

输入:nums = [7,12,9,8,9,15], k = 4
输出:9
解释:nums[0]、nums[2]、nums[4] 和 nums[5] 的第 0 位的值为 1 。
nums[0] 和 nums[5] 的第 1 位的值为 1 。
nums[0]、nums[1] 和 nums[5] 的第 2 位的值为 1 。
nums[1]、nums[2]、nums[3]、nums[4] 和 nums[5] 的第 3 位的值为 1 。
只有第 0 位和第 3 位满足数组中至少存在 k 个元素在对应位上的值为 1 。因此,答案为 2^0 + 2^3 = 9 。

示例 2:

输入:nums = [2,12,1,11,4,5], k = 6
输出:0
解释:因为 k == 6 == nums.length ,所以数组的 6-or 等于其中所有元素按位与运算的结果。因此,答案为 2 AND 12 AND 1 AND 11 AND 4 AND 5 = 0 。

示例 3:

输入:nums = [10,8,5,9,11,6,8], k = 1
输出:15
解释:因为 k == 1 ,数组的 1-or 等于其中所有元素按位或运算的结果。因此,答案为 10 OR 8 OR 5 OR 9 OR 11 OR 6 OR 8 = 15 。

提示:

  • 1 <= nums.length <= 50
  • 0 <= nums[i] < 231
  • 1 <= k <= nums.length

位运算模拟

class Solution {
    public int findKOr(int[] nums, int k) {
        int res = 0;
        for(int i = 0; i < 32; i++){
            int cnt = 0;
            for(int num : nums){
                if(((num >> i) & 1) == 1)
                    cnt += 1;
            }
            if(cnt >= k)
                res |= (1 << i);
        }
        return res;
    }
}

2918. 数组的最小相等和

中等

给你两个由正整数和 0 组成的数组 nums1nums2

你必须将两个数组中的 所有 0 替换为 严格 正整数,并且满足两个数组中所有元素的和 相等

返回 最小 相等和 ,如果无法使两数组相等,则返回 -1

示例 1:

输入:nums1 = [3,2,0,1,0], nums2 = [6,5,0]
输出:12
解释:可以按下述方式替换数组中的 0 :
- 用 2 和 4 替换 nums1 中的两个 0 。得到 nums1 = [3,2,2,1,4] 。
- 用 1 替换 nums2 中的一个 0 。得到 nums2 = [6,5,1] 。
两个数组的元素和相等,都等于 12 。可以证明这是可以获得的最小相等和。

示例 2:

输入:nums1 = [2,0,2,0], nums2 = [1,4]
输出:-1
解释:无法使两个数组的和相等。

提示:

  • 1 <= nums1.length, nums2.length <= 105
  • 0 <= nums1[i], nums2[i] <= 106

分类讨论

class Solution {
    /**
    只有四种情况,依次分类讨论,注意无法相等的情况
     */
    public long minSum(int[] nums1, int[] nums2) {
        int cnt01 = 0, cnt02 = 0;
        long sum1 = 0, sum2 = 0;
        for(int num : nums1){
            if(num == 0) cnt01 += 1;
            sum1 += num;
        }
        for(int num : nums2){
            if(num == 0) cnt02 += 1;
            sum2 += num;
        }
        if(cnt01 > 0 && cnt02 > 0)
            return Math.max(cnt01 + sum1, cnt02 + sum2);
        else if(cnt01 == 0 && cnt02 == 0)
            return cnt01 + sum1 == cnt02 + sum2 ? cnt01 + sum1 : -1;
        else{
            if(cnt01 == 0){
                if(sum1 < cnt02 + sum2) return -1;
                return sum1;
            }else{
                if(sum2 < cnt01 + sum1) return -1;
                return sum2;
            }
        }
    }
}

2919. 使数组变美的最小增量运算数

中等

给你一个下标从 0 开始、长度为 n 的整数数组 nums ,和一个整数 k

你可以执行下述 递增 运算 任意 次(可以是 0 次):

  • 从范围 [0, n - 1] 中选择一个下标 i ,并将 nums[i] 的值加 1

如果数组中任何长度 大于或等于 3 的子数组,其 最大 元素都大于或等于 k ,则认为数组是一个 美丽数组

以整数形式返回使数组变为 美丽数组 需要执行的 最小 递增运算数。

子数组是数组中的一个连续 非空 元素序列。

示例 1:

输入:nums = [2,3,0,0,2], k = 4
输出:3
解释:可以执行下述递增运算,使 nums 变为美丽数组:
选择下标 i = 1 ,并且将 nums[1] 的值加 1 -> [2,4,0,0,2] 。
选择下标 i = 4 ,并且将 nums[4] 的值加 1 -> [2,4,0,0,3] 。
选择下标 i = 4 ,并且将 nums[4] 的值加 1 -> [2,4,0,0,4] 。
长度大于或等于 3 的子数组为 [2,4,0], [4,0,0], [0,0,4], [2,4,0,0], [4,0,0,4], [2,4,0,0,4] 。
在所有子数组中,最大元素都等于 k = 4 ,所以 nums 现在是美丽数组。
可以证明无法用少于 3 次递增运算使 nums 变为美丽数组。
因此,答案为 3 。

示例 2:

输入:nums = [0,1,3,3], k = 5
输出:2
解释:可以执行下述递增运算,使 nums 变为美丽数组:
选择下标 i = 2 ,并且将 nums[2] 的值加 1 -> [0,1,4,3] 。
选择下标 i = 2 ,并且将 nums[2] 的值加 1 -> [0,1,5,3] 。
长度大于或等于 3 的子数组为 [0,1,5]、[1,5,3]、[0,1,5,3] 。
在所有子数组中,最大元素都等于 k = 5 ,所以 nums 现在是美丽数组。
可以证明无法用少于 2 次递增运算使 nums 变为美丽数组。 
因此,答案为 2 。

示例 3:

输入:nums = [1,1,2], k = 1
输出:0
解释:在这个示例中,只有一个长度大于或等于 3 的子数组 [1,1,2] 。
其最大元素 2 已经大于 k = 1 ,所以无需执行任何增量运算。
因此,答案为 0 。

提示:

  • 3 <= n == nums.length <= 105
  • 0 <= nums[i] <= 109
  • 0 <= k <= 109

记忆化搜索 ==> 动态规划

https://leetcode.cn/problems/minimum-increment-operations-to-make-array-beautiful/solutions/2503157/qiao-miao-she-ji-zhuang-tai-xuan-huo-bu-8547u/

class Solution {
    int[] nums;
    long[][] cache;
    int k;
    public long minIncrementOperations(int[] nums, int k) {
        this.k = k;
        this.nums = nums;
        int n = nums.length;
        cache = new long[n][3];
        for(int i = 0; i < n; i++)
            Arrays.fill(cache[i], -1);
        return dfs(n-1, 0);
    }
    /**
        问题转换成:把每个长为 3 的子数组都需要包含至少一个k
        考虑最后一个元素选还是不选,即是否增大
            增大到k:那么对于左边的那个数来说,它右边就有一个k
            不增大:那么对于左边那个数来说,它右边有一个没有增大的数
        定义 dfs(i, j) 表示当前在i位置,右边有j个没有增大的数
            增大到k 即 dfs(i-1, 0) + max(k - nums[i], 0)
            如果 j < 2,即可以不增大,dfs(i-1, j+1)
        递归边界 当 i < 0 时返回0
        递归入口 dfs(n-1, 0)
     */ 
    public long dfs(int i, int j){
        if(i < 0) return 0;
        if(cache[i][j] >= 0) return cache[i][j];
        long res = dfs(i-1, 0) + Math.max(k - nums[i], 0);
        if(j < 2) res = Math.min(res, dfs(i-1, j+1));
        return cache[i][j] = res;
    }
}

2920. 收集所有金币可获得的最大积分

困难

节点 0 处现有一棵由 n 个节点组成的无向树,节点编号从 0n - 1 。给你一个长度为 n - 1 的二维 整数 数组 edges ,其中 edges[i] = [ai, bi] 表示在树上的节点 aibi 之间存在一条边。另给你一个下标从 0 开始、长度为 n 的数组 coins 和一个整数 k ,其中 coins[i] 表示节点 i 处的金币数量。

从根节点开始,你必须收集所有金币。要想收集节点上的金币,必须先收集该节点的祖先节点上的金币。

节点 i 上的金币可以用下述方法之一进行收集:

  • 收集所有金币,得到共计 coins[i] - k 点积分。如果 coins[i] - k 是负数,你将会失去 abs(coins[i] - k) 点积分。
  • 收集所有金币,得到共计 floor(coins[i] / 2) 点积分。如果采用这种方法,节点 i 子树中所有节点 j 的金币数 coins[j] 将会减少至 floor(coins[j] / 2)

返回收集 所有 树节点的金币之后可以获得的最大积分。

示例 1:

img

输入:edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
输出:11                        
解释:
使用第一种方法收集节点 0 上的所有金币。总积分 = 10 - 5 = 5 。
使用第一种方法收集节点 1 上的所有金币。总积分 = 5 + (10 - 5) = 10 。
使用第二种方法收集节点 2 上的所有金币。所以节点 3 上的金币将会变为 floor(3 / 2) = 1 ,总积分 = 10 + floor(3 / 2) = 11 。
使用第二种方法收集节点 3 上的所有金币。总积分 =  11 + floor(1 / 2) = 11.
可以证明收集所有节点上的金币能获得的最大积分是 11 。 

示例 2:

img

输入:edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
输出:16
解释:
使用第一种方法收集所有节点上的金币,因此,总积分 = (8 - 0) + (4 - 0) + (4 - 0) = 16 。

提示:

  • n == coins.length
  • 2 <= n <= 105
  • 0 <= coins[i] <= 104
  • edges.length == n - 1
  • 0 <= edges[i][0], edges[i][1] < n
  • 0 <= k <= 104

树形DP

https://leetcode.cn/problems/maximum-points-after-collecting-coins-from-all-nodes/solutions/2503152/shu-xing-dp-ji-yi-hua-sou-suo-by-endless-phzx/

class Solution {
    /**
    把 floor(coins[i]/2) 看成右移操作,右移操作是可以叠加的,
            我们可以记录子树节点右移了多少次
    10^4 = 14次,本题最多右移14次就成为了0
    定义dfs(i, j) 表示子树 i 在已经右移了j次的前提下,最多可以获得多少积分
    用 选或者不选 来思考
    右移 答案为 coins[i] >> (j+1) 加上每个子树 ch 的dfs(ch, j+1)
    不右移 答案为 (coins[i]>>j)-k 加上每个子树 ch 的dfs(ch, j)
     */
    public int maximumPoints(int[][] edges, int[] coins, int k) {
        int n = coins.length;
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for(int[] e : edges){
            int x = e[0], y = e[1];
            g[x].add(y);
            g[y].add(x);
        }
        int[][] cache = new int[n][14];
        for(int[] m : cache)
            Arrays.fill(m, -1);
        return dfs(0, 0, -1, cache, g, coins, k);
    }

    public int dfs(int i, int j, int fa, int[][] memo, List<Integer>[] g, int[] coins, int k){
        if(memo[i][j] != -1)
            return memo[i][j];
        int res1 = (coins[i] >> j) - k;
        int res2 = coins[i] >> (j+1);
        for(int ch : g[i]){
            if(ch == fa) continue;
            // 不右移
            res1 += dfs(ch, j, i, memo, g, coins, k);
            // 右移
            if(j < 13){
                res2 += dfs(ch, j + 1, i, memo, g, coins, k);
            }
        }
        return memo[i][j] = Math.max(res1, res2);
    }
}

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

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

相关文章

计算机学院的老师们的实际编程能力如何?

计算机学院的老师们的实际编程能力如何&#xff1f; 国内的多数老师基本上就是学术界&#xff0c;工业界&#xff0c;教育界&#xff0c;这三个领域哪个他们都不沾边&#xff0c;几乎就是混日子&#xff0c;顺便能多混点钱就多混点钱的那种。 最近很多小伙伴找我&#xff0c;…

Day18力扣打卡

打卡记录 寻找重复数&#xff08;双指针&#xff09; 链接 Floyd判圈法&#xff0c;先用快慢指针以不同速率进行移动&#xff0c;最终一定会出现相遇点&#xff0c;然后在使一指针从初始开始&#xff0c;两指针再以同步调移动&#xff0c;再次相遇的点一定为循环开始的点位。 …

mysql 中!= 到底走不走索引?

mysql 中! 到底走不走索引&#xff1f; 很多人疑惑! 到底走不走索引&#xff0c; 这里可以肯定的说该操作是可以走索引的&#xff0c;但实际情况中都为啥都不走索引呢&#xff1f; 首先我们要知道走索引与数据量和数据趋势&#xff08;cardinality&#xff09;有很大的关系&…

用于比例方向控制阀的电控模块

比例方向控制阀电控放大器是一种电子装置&#xff0c;其主要功能是对弱电的控制信号进行整形、运算和功率放大&#xff0c;从而驱动比例方向控制阀。用于无位置传感器的比例方向控制阀。 通过控制PWM脉冲的占空比&#xff0c;可以控制比例阀端口的驱动电流&#xff0c;进而达到…

SelectorsHub插件使用教程

一、安装 进入chrome商店进行安装 二、使用SelectorsHub复制xpath 三、检查复制的xpath是否正确 1、右键检查 2、ctrlf&#xff0c;进行查找 3、复制xpath到查找框内 4、可以看出查找出一个元素 四、复制不同xpath的区别 1、copy relative xpath 相对XPath是相对于当前元素…

memtest86 prosite v10.6

passmark官方的memtest86 v10开始支持颗粒级别的坏内存芯片定位了&#xff0c;对于特定的若干种CPU和芯片组的组合&#xff0c;支持这项功能。 当然支持颗粒定位的site版本售价4800美金&#xff0c;是比较贵的。所以网络上出现了破解版的&#xff0c;人才真是。但是鼓励大家支…

运维基础-Docker容器命令部署

Docker基础知识 安装问题-有podmanCentos8使用yum install docker -y时&#xff0c;默认安装的是podman-docker软件安装docker yum list installed | grep dockeryum -y remove xxxxDocker安装配置下载安装docker启动docker&#xff0c;并设置开机启动下载所需镜像 centos镜像进…

精品基于Python的汽车销售趋势分析-爬虫可视化大屏

《[含文档PPT源码等]精品基于Python的汽车销售趋势分析-爬虫》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&…

NiceGui:Python中的轻量级GUI框架初体验

目录 一、引言 二、NiceGui概述 三、NiceGui实战&#xff1a;一个简单的计算器应用 四、NiceGui与其他GUI框架的比较 五、注意事项 总结与展望 一、引言 Python作为一门功能强大且易于学习的编程语言&#xff0c;广泛应用于各种领域。在图形用户界面&#xff08;GUI&…

【实战Flask API项目指南】之二 Flask基础知识

实战Flask API项目指南之 Flask基础知识 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发的世界&…

CodeWhisperer 的安装及体验

文章作者&#xff1a;Pony CodeWhisperer 是亚马逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。类似 Cursor 和 Github Copilot 编码工具。 官网&#xff1a;https://aws.amazon.com/cn/codewhisperer/?trkcndc-detail 在编写代码时&#xff0c…

【unity3D】使用RawImage实现UI上的帧动画

&#x1f4a6;本专栏是我关于游戏开发的笔记 &#x1f236;本篇是一个简短的小知识点 使用RawImage实现帧动画 找一个帧动画连续的图片拖到工程中&#xff0c;将Texture Type改成Sprite&#xff08;2D和UI&#xff09;&#xff0c;点击apply应用上 在工程中新建一个RawImage,将…

0基础学习VR全景平台篇第117篇:利用插件地拍补地 - PS教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 嗨&#xff0c;大家好&#xff0c;今天我们来介绍【PS利用插件地拍补地】。 之前已经教给大家补地插件的安装方法&#xff0c;今天我们教给大家如何使用这个插件进行补地。 首…

Android和JNI交互 : 常见的图像格式转换 : NV21、RGBA、Bitmap等

1. 前言 最近在使用OpenCV处理图片的时候&#xff0c;经常会遇到需要转换图像的情况&#xff0c;网上相关资料比较少&#xff0c;也不全&#xff0c;有时候得费劲老半天才能搞定。 自己踩了坑后&#xff0c;在这里记录下&#xff0c;都是我在项目中遇到的图像转化操作&#xf…

unity3d 开发笔记

unity 3d Unity是一个游戏引擎&#xff0c;包含渲染引擎&#xff0c;物理引擎&#xff0c;碰撞检测&#xff0c;音效&#xff0c;动画效果&#xff0c;场景管理等系统。它的开发效率高、脚本使用C#开发、简单易用、跨平台&#xff08;可以导出各个平台的程序&#xff09;&…

abbyy15有哪些新功能更新改进?

可以说优化文档过程&#xff1a;ABBYY在一个工作流中对各种类型的文档进行数字化、检索、编辑、保护、共享和协作。不得不承认FineReader 15最大特色是采用了ABBYY最新推出的基于AI的OCR技术&#xff0c;能够更快速的在同一工作流程中对各种文档进行数字化、检索、编辑、加密、…

【原创】java+swing+mysql汽车租赁管理系统设计与实现

摘要&#xff1a; 汽车租赁管理系统是一个综合性的系统&#xff0c;旨在实现汽车租赁过程的自动化和优化。它涵盖了从客户预订、车辆管理&#xff0c;通过设计和实现汽车租赁管理系统&#xff0c;可以提高汽车租赁公司的运营效率和服务质量&#xff0c;降低运营成本&#xff0…

45基于matlab的ARIMA:AutoregressiveIntegratedMovingAverage model。

基于matlab的ARIMA&#xff1a;AutoregressiveIntegratedMovingAverage model。自回归差分移动平均模型(p,d,q)&#xff0c;AR自回归模型&#xff0c;MA移动平均模型&#xff0c;时间序列模型步骤包括&#xff1a;1. 数据平稳性检验&#xff1b;2. 确定模型参数&#xff1b;3. …

快速了解相似检索方法

一、相似检索方法总体分析 相似检索方法是一种用于从大量数据中找到与查询数据相似的数据项的技术。这种方法通常用于信息检索、推荐系统、图像处理、自然语言处理等领域。相似检索主要方法可以总体分为以下几类&#xff1a; 基于距离度量的方法&#xff1a; 余弦相似度&…

国产手机纷自研操作系统,“不作恶”的谷歌自食恶果

在中国第一家手机企业自研操作系统并取得成功之后&#xff0c;日前再有两家国产手机宣布自研操作系统&#xff0c;由此将导致安卓系统的基座开始被撼动&#xff0c;垄断很可能将就此终结。 谷歌曾声称自己“不作恶”&#xff0c;不过在安卓系统发展壮大之后&#xff0c;谷歌开始…