LC-1262. 可被三整除的最大和(状态机DP)

news2024/11/25 10:43:32

1262. 可被三整除的最大和

难度中等229

给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和。

示例 1:

输入:nums = [3,6,5,1,8]
输出:18
解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。

示例 2:

输入:nums = [4]
输出:0
解释:4 不能被 3 整除,所以无法选出数字,返回 0。

示例 3:

输入:nums = [1,2,3,4,4]
输出:12
解释:选出数字 1, 3, 4 以及 4,它们的和是 12(可被 3 整除的最大和)。

提示:

  • 1 <= nums.length <= 4 * 10^4
  • 1 <= nums[i] <= 10^4

状态机DP

https://leetcode.cn/problems/greatest-sum-divisible-by-three/solution/dong-tai-gui-hua-yu-zhuang-tai-zhuan-yi-by-christm/

1、状态定义

  • dp[i][0]表示nums[0...i]模三余零的最大和
  • dp[i][1]表示nums[0...i]模三余一的最大和
  • dp[i][2]表示nums[0...i]模三余二的最大和
  • 零状态:当前数字最大和模三余零
  • 一状态:当前数字最大和模三余一
  • 二状态:当前数字最大和模三余二

2、状态转移

对于任意一种状态,下一步我们都有两种选择,一是选择当前元素二是不选择当前元素

dp[i][*] = max{dp[i-1][*],dp[i-1][*] + nums[i]}  (* 取值为 0,1,2)

以上是常见的动态规划的递推结构

本题的状态转移显而易见,以当前状态是零状态为例。我们可以想到,前一个状态无非是零状态、一状态、二状态,三种情况,针对这三种情况我们分类讨论即可

class Solution {
    public int maxSumDivThree(int[] nums) {
        int n = nums.length;
        int[][] dp = new int[n+1][3];
        // 初值,不存在余1和余2的情况
        dp[0][0] = 0; dp[0][1] = Integer.MIN_VALUE; dp[0][2] = Integer.MIN_VALUE;
        for(int i = 1; i <= n; i++){
            if(nums[i-1] % 3 == 0){
                dp[i][0] = Math.max(dp[i-1][0], dp[i-1][0] + nums[i-1]);
                dp[i][1] = Math.max(dp[i-1][1], dp[i-1][1] + nums[i-1]);
                dp[i][2] = Math.max(dp[i-1][2], dp[i-1][2] + nums[i-1]);
            }else if(nums[i-1] % 3 == 1){
                dp[i][0] = Math.max(dp[i-1][0], dp[i-1][2] + nums[i-1]);
                dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + nums[i-1]);
                dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1] + nums[i-1]);
            }else{ // nums[i-1] % 3 == 2
                dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + nums[i-1]);
                dp[i][1] = Math.max(dp[i-1][1], dp[i-1][2] + nums[i-1]);
                dp[i][2] = Math.max(dp[i-1][2], dp[i-1][0] + nums[i-1]);
            }
        }
        return dp[n][0]; // 返回模三余0 的值
    }
}

21.4.5 网易互联网C++笔试改版成 可被6整除的最大和

22.3.26 美团改成7了

动态规划(更一般性的状态机DP)

https://leetcode.cn/problems/greatest-sum-divisible-by-three/solution/liang-chong-suan-fa-tan-xin-dong-tai-gui-tsll/

讨论:

用【选或不选】的思路,考虑最后一个数 x = nums[n-1]
如果 x mod 3 = 0,那么 x 一定要选,问题变成从 nums[0] 到 nums[n-2] 中寻找能被 3 整除的元素最大和。
如果 x mod 3 = 1:
    如果不选 x,和上面一样,问题变成从 nums[0] 到 nums[n-2] 中寻找能被 3 整除的元素最大和 s0。
    如果选 x,问题变成从 nums[0] 到 nums[n-2] 中寻找最大元素和s2 满足 s2 mod 3 = 2,答案为 max(so,s2 +x)。
如果 x mod 3 = 2:
    如果不选 x,和上面一样,问题变成从 nums[0] 到 nums[n-2] 中寻找能被 3 整除的元素最大和 s0。
    如果选 x,问题变成从 nums[0] 到 nums[n-2] 中寻找最大元素和s1 满足 s1 mod 3 = 1,答案为 max(so,s1 +x)。
---------------------------------------------------
上述讨论,刻画了这道题的两个重要参数
	i: 表示从 nums[0]到 nums[i] 中选数
	j: 表示所选数字之和 s 需要满足 s mod 3 = j。
那么原问题就是 (i = n-1,j = 0),上述讨论得到的子问题有 (i= n-2,j=0),(i = n - 2,j = 1),(i = n - 2,j = 2)。
注: 为什么要从最后一个数开始讨论? 主要是为了方便后面把记忆化搜索改成递推。当然,你从第一个数开始讨论也是可以的。

记忆化搜索

class Solution:
    def maxSumDivThree(self, nums: List[int]) -> int:
        # 定义 dfs(i,j) 表示从 nums[0] 到 nums[i] 中选数, 所选数字之和 s 满足 s mod 3 =j的前提下, s的最大值
        @cache
        def dfs(i, j: int) -> int:
            if i < 0: return -inf if j else 0
            return max(dfs(i-1, j), dfs(i-1, (j + nums[i]) % 3) + nums[i])
        return dfs(len(nums)-1, 0)

转成递推

class Solution {
    public int maxSumDivThree(int[] nums) {
        int n = nums.length;
        int[][] f = new int[n+1][3];
        f[0][0] = 0;
        f[0][1] = Integer.MIN_VALUE;
        f[0][2] = Integer.MIN_VALUE;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < 3; j++)
                f[i+1][j] = Math.max(f[i][j], f[i][(j+nums[i]) % 3] + nums[i]);
        }
        return f[n][0];
    }
}

空间优化:(用滚动数组优化空间)

由于 f[i + 1] 只依赖 f,那么 f[i - 1] 及其之前的数据就没用了

class Solution {
    public int maxSumDivThree(int[] nums) {
        int n = nums.length;
        int[] f = new int[3];
        f[0] = 0;
        f[1] = Integer.MIN_VALUE;
        f[2] = Integer.MIN_VALUE;
        for(int i = 0; i < n; i++){
            int[] tmp = Arrays.copyOf(f, 3);
            for(int j = 0; j < 3; j++)
                f[j] = Math.max(tmp[j], tmp[(j+nums[i]) % 3] + nums[i]);
            tmp = f;
        }
        return f[0];
    }
}

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

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

相关文章

图的操作算法详解

一.图 基础概念&#xff1a; 有向图 - 图中每个边都有一个方向&#xff0c;例如社交媒体网站上的关注关系图就是有向图。无向图 - 图中每个边都没有方向&#xff0c;例如朋友之间的相互认识关系图可以是无向图。简单图 - 没有自环和重复边的无向图或有向图&#xff0c;例如一…

025.【树形结构算法】

1. 树的定义 树形结构是由n个元素组成的有限集合&#xff0c;如果n0&#xff0c;那么就称为空树&#xff1b;如果n>0&#xff0c;树形结构应该满足以下条件&#xff1a; 有一个特定的结点&#xff0c;称为根结点或根。 除根结点外&#xff0c;其余结点被分成m(m≥0)个互不…

面试官:一个 TCP 连接可以发多少个 HTTP 请求?

目录 &#x1f914; 第一个问题 &#x1f914; 第二个问题 &#x1f914; 第三个问题 &#x1f914; 第四个问题 &#x1f914; 第五个问题 曾经有这么一道经典面试题&#xff1a;从 URL 在浏览器被被输入到页面展现的过程中发生了什么&#xff1f; 相信大多数准备过的同…

产品经理面试常见的25个必问题(一)

1、你认为产品经理的工作职责是什么&#xff1f; ●需求阶段&#xff08;需求收集、需求管理、需求分析、需求评估&#xff09; ●设计阶段&#xff08;业务流程、功能模块、原型交互、需求文档&#xff09; ●开发阶段&#xff08;需求评审、项目管理、测试验收&#xff09…

centos版本的EDA虚拟机搭建1

0、参考博客 Centos镜像国内最全下载地址 VMware Workstation CPU如何设置才更加合理&#xff1f;如何才能发挥虚拟机最大性能 1、下载网站 http://mirrors.aliyun.com/centos/7/isos/x86_64/centos镜像文件下载完成。 2、vmware搭建centos 新建虚拟机。 选择自定义。 …

mysql中的索引

1、索引是什么&#xff1f; 在mysql当中&#xff0c; 内部系统它有两种查询方式&#xff0c; 一种是(全盘扫描查询)&#xff0c;另外一种是通过(索引检索查询)&#xff0c;通过添加了索引的字段进行查询&#xff0c; 可以大大提高查询效率 mysql中的索引相当于一本书中的目录&a…

java 物流配货管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 物流配货管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

centos7系统:HAProxy软件部署

目录 目 的&#xff1a; 硬件需求: ​编辑 实验环境配置&#xff1a; haproxy的服务器配置&#xff1a; nfsrps服务器部署&#xff1a; nginx服务器1部署: nginx服务器2部署&#xff1a; 目 的&#xff1a; 两台nginx服务器做web服务&#xff0c;haproxy服务器做调度负载均…

(6.9-6.15)【大数据新闻速递】

【上海数交所将携手清华大学等举办首届数据资产入表研修班】 上海数据交易所获悉&#xff0c;数交所将联合清华大学五道口金融学院、上海市数商协会于6月28日至29日举办首届数据资产入表研修班。财政部印发《企业数据资源相关会计处理暂行规定&#xff08;征求意见稿&#xff…

前沿应用丨大规模无人机集群与“虚实结合”半实物仿真系统

一、应用背景 无人机集群在军事、安全、救援、航空监测、物流配送等领域具有广泛的应用前景。它可以提高任务执行的效率、灵活性和安全性&#xff0c;同时降低人力资源的需求和风险&#xff0c;无人机集群研究涉及多个学科领域&#xff0c;如机器人学、控制理论、通信技术和人工…

【算法与数据结构】383、LeetCode赎金信

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;这道题的思路和242、有效的字母异位词的思路一样   程序如下&#xff1a; class Solution { public…

好好存钱,是成年人最顶级的自律

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 王尔德说&#xff1a;“在我年轻的时候&#xff0c;曾以为金钱是世界上最重要的东西。现在我老了&#xff0c;才知道的确如此。” 路遥说&#xff1a;“钱是好东西&#xff0c;它能使人不再心慌&#…

指纹识别工具WhatWeb使用教程,图文教程(超详细)

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 WhatWeb 一、扫描网站指纹二、扫描强度三、扫描内网…

ZeroQuant-V2 LLM权重与激活量化

ref ZeroQuant-V2: Exploring Post-training Quantization in LLMs from Comprehensive Study to Low Rank Compensation 4bit量化为什么重要 The case for 4-bit precision: k-bit Inference Scaling Laws 这篇文章研究表明4bit通常是最优的量化方法&#xff1a;同样的量化…

快速选择合适的GNSS模拟器,看这几个重点

为了正确测试GNSS接收器或其他任何依赖GNSS信号的系统或设备&#xff0c;工程师需要模拟与真实卫星广播相同的RF信号&#xff0c;而使用GNSS模拟器是实现这一工作的最佳选择。 假设正在开发一种需要集成GNSS接收器的新产品&#xff0c;想要验证接收器设备在不同条件下是否运行…

企业为什么要关注库存?因为那都是“钱”!

库存是企业管理的核心&#xff0c;公司必须提供足够的商品来满足客户需求&#xff0c;但又不能冒着浪费金钱和资源的风险&#xff0c;一味的增加库存。 不同的企业在库存管理这个问题上就“八仙过海各显神通”了&#xff0c;常见的处理方法有&#xff1a; 1. 经验法&#xff1a…

求两数之和

必应壁纸供图 题目描述 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不…

基于SpringBoot+Vue的学生毕业离校系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

Sui x KuCoin Labs夏季黑客松首批入围项目公布

经过一段时间的共同努力&#xff0c;我们已经完成了对Sui x KuCoin Labs夏季黑客松第一批入围项目的审核&#xff0c;并宣布以下团队已入围最终demo day&#xff1a; 首批入围名单 Desig Protocol Desig协议提供了一种与区块链无关&#xff08;无智能合约&#xff09;的多重…

聚观早报|奔驰接入ChatGPT聊天机器人;极兔速递提交上市申请书

今日要闻&#xff1a;奔驰接入ChatGPT聊天机器人&#xff1b;极兔速递向港交所提交上市申请书&#xff1b;微软股价创历史新高&#xff1b;美电动卡车Nikola宣布裁员23%&#xff1b;马斯克&#xff1a;人工智能具有颠覆性 奔驰接入ChatGPT聊天机器人 梅赛德斯 - 奔驰表示&…