【LeetCode: 1043. 分隔数组以得到最大和 | 暴力递归=>记忆化搜索=>动态规划 | 线性dp 区间dp】

news2024/12/23 13:24:12

在这里插入图片描述

🚀 算法题 🚀

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

🚀 算法题 🚀

在这里插入图片描述

🍔 目录

    • 🚩 题目链接
    • ⛲ 题目描述
    • 🌟 线性dp&求解思路&实现代码&运行结果
      • ⚡ 暴力递归
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 记忆化搜索
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 动态规划
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
    • 🌟 区间dp&求解思路&实现代码&运行结果
      • ⚡ 暴力递归
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 记忆化搜索
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
      • ⚡ 动态规划
        • 🥦 求解思路
        • 🥦 实现代码
        • 🥦 运行结果
    • 💬 共勉

🚩 题目链接

  • 1043. 分隔数组以得到最大和

⛲ 题目描述

给你一个整数数组 arr,请你将该数组分隔为长度 最多 为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。

返回将数组分隔变换后能够得到的元素最大和。本题所用到的测试用例会确保答案是一个 32 位整数。

示例 1:

输入:arr = [1,15,7,9,2,5,10], k = 3
输出:84
解释:数组变为 [15,15,15,9,10,10,10]
示例 2:

输入:arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
输出:83
示例 3:

输入:arr = [1], k = 1
输出:1

提示:

1 <= arr.length <= 500
0 <= arr[i] <= 109
1 <= k <= arr.length

🌟 线性dp&求解思路&实现代码&运行结果


⚡ 暴力递归

🥦 求解思路

  1. 首先根据题目的意思我们知道,题目让我们去求将数组划分成多个长度不超过k的子数组,每一个子数组的值更新为当前子数组中最大的值,最后求得所有划分方案中所有子数组最大的和并返回。
  2. 那么这个题我们该怎么想呢?因为可以划分的长度最大是k,所以我们可以枚举所有k的选择;
  3. 那么什么时候去求每个子数组贡献的结果呢?我们可以在遍历的时候,记录当前选择长度内的最大值,然后在调用递归的时候通过之前子数组中的最大值*个数累加到最终的结果中;
  4. 有了基本的思路,接下来我们就来一起实现代码吧。

🥦 实现代码

class Solution {
    public int maxSumAfterPartitioning(int[] arr, int k) {
        return process(0,arr,k);
    }

    public int process(int index,int[] arr,int k){
        if(index>=arr.length) return 0;
        int max=0,num=0;
        for(int i=index;i<Math.min(index+k,arr.length);i++){
            num=Math.max(num,arr[i]);
            max=Math.max(max,process(i+1,arr,k)+num*(i-index+1));
        }
        return max;
    }
}

🥦 运行结果

时间超限了,不要紧哦,我还有锦囊妙计!

在这里插入图片描述


⚡ 记忆化搜索

🥦 求解思路

  1. 根据我们递归的分析,在递归的过程中会产生重复的子过程,所以我们想到了加一个缓存表,也就是我们的记忆化搜索。

🥦 实现代码

class Solution {
    int[] dp;
    public int maxSumAfterPartitioning(int[] arr, int k) {
        dp=new int[arr.length];
        Arrays.fill(dp,-1);
        return process(0,arr,k);
    }

    public int process(int index,int[] arr,int k){
        if(index>=arr.length) return 0;
        if(dp[index]!=-1) return dp[index];
        int max=0,num=0;
        for(int i=index;i<Math.min(index+k,arr.length);i++){
            num=Math.max(num,arr[i]);
            max=Math.max(max,process(i+1,arr,k)+num*(i-index+1));
        }
        return dp[index]=max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 动态规划

🥦 求解思路

  1. 按照我们之前递归和记忆化搜索的思路,通过动态规划实现出来。

🥦 实现代码

class Solution {
    int[] dp;
    public int maxSumAfterPartitioning(int[] arr, int k) {
        int n=arr.length;
        dp=new int[n+1];
        for(int index=n-1;index>=0;index--){
            int max=0,num=0;
            for(int i=index;i<Math.min(index+k,n);i++){
                num=Math.max(num,arr[i]);
                max=Math.max(max,dp[i+1]+num*(i-index+1));
            }
            dp[index]=max;
        }
        return dp[0];
    }
}

🥦 运行结果

在这里插入图片描述


🌟 区间dp&求解思路&实现代码&运行结果


⚡ 暴力递归

🥦 求解思路

  1. 为什么会想到这种递归思路呢?因为题目要我们从开始位置到结束位置进行切割子数组,每个子数组的长度最多可能达到k,此时我们从0位置开始,可以选择的下一个位置小于k即可([0_k-1]都是可以的),如果说此时我们选择了[0_k-2]进行切割,那么后续的问题就拆解成了[k-1_n-1]的规模,那么整个问题的求解是相同的,并且大规模可以拆解为小规模,此时我们通过递归来做就可以,后续直接改成动态规划。
  2. 有了具体的实现思路,接下来我们就来一起看一下代码的实现。

🥦 实现代码

class Solution {

    public int maxSumAfterPartitioning(int[] arr, int k) {
        return process(0,arr,k,arr.length-1);
    }

    public int process(int left,int[] arr,int k,int right){
        if(left>right) return 0;
        if(right-left<k){
            int num=0;
            for(int i=left;i<=right;i++) num=Math.max(num,arr[i]);
            return num*(right-left+1);
        }
        int max=0;
        for(int i=left;i<left+k;i++){
            max=Math.max(max,process(left,arr,k,i)+process(i+1,arr,k,right));
        }
        return max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 记忆化搜索

🥦 求解思路

  1. 根据我们递归的分析,在递归的过程中会产生重复的子过程,所以我们想到了加一个缓存表,也就是我们的记忆化搜索。

🥦 实现代码

class Solution {

    int[][] dp;

    public int maxSumAfterPartitioning(int[] arr, int k) {
        int n=arr.length;
        dp=new int[n][n];
        for(int i=0;i<n;i++) Arrays.fill(dp[i],-1);
        return process(0,arr,k,arr.length-1);
    }


    public int process(int left,int[] arr,int k,int right){
        if(left>right) return 0;
        if(right-left<k){
            int num=0;
            for(int i=left;i<=right;i++) num=Math.max(num,arr[i]);
            return num*(right-left+1);
        }
        if(dp[left][right]!=-1) return dp[left][right];
        int max=0;
        for(int i=left;i<left+k;i++){
            max=Math.max(max,process(left,arr,k,i)+process(i+1,arr,k,right));
        }
        return dp[left][right]=max;
    }
}

🥦 运行结果

在这里插入图片描述


⚡ 动态规划

🥦 求解思路

  1. 按照我们之前递归和记忆化搜索的思路,通过动态规划实现出来。

🥦 实现代码

class Solution {

    int[][] dp;

    public int maxSumAfterPartitioning(int[] arr, int k) {
        int n=arr.length;
        dp=new int[n][n];
        for(int i=0;i<n;i++) Arrays.fill(dp[i],-1);
        for(int left=0;left<n;left++){
            for(int right=0;right<n;right++){
                if(right-left<k){
                    int num=0;
                    for(int i=left;i<=right;i++) num=Math.max(num,arr[i]);
                    dp[left][right]=num*(right-left+1);
                }
            }
        }
        for(int left=n-k-1;left>=0;left--){
            for(int right=left+k-1;right<n;right++){
                int max=0;
                for(int i=left;i<left+k;i++){
                    max=Math.max(max,dp[left][i]+dp[i+1][right]);
                }
                dp[left][right]=max;
            }
        }
        return dp[0][n-1];
    }
}

🥦 运行结果

在这里插入图片描述


💬 共勉

最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

使用ETL工具Sqoop,将MySQL数据库db03中的10张表的表结构和数据导入(同步)到大数据平台的Hive中

在MySQL中&#xff0c;创建一个用户&#xff0c;用户名为sqoop03&#xff0c;密码为&#xff1a;123456 启动MySQL&#xff1a;support-files/mysql.server start 进入MySQL&#xff1a;mysql -u root -p 创建用户sqoop03&#xff1a;grant all on *.* to sqoop03% identifi…

5.5 高斯型求积公式简历

学习目标&#xff1a; 我会按照以下步骤学习高斯求积公式简介&#xff1a; 理解积分的概念&#xff1a;学习什么是积分以及积分的几何和物理意义&#xff0c;如面积、质量、电荷等概念。 掌握基本的积分技巧&#xff1a;掌握基本的积分公式和技巧&#xff0c;如换元法、分部积…

重要通知!报表控件FastReport VCL将停止支持旧的 Delphi 版本

FastReport 是功能齐全的报表控件&#xff0c;可以帮助开发者可以快速并高效地为.NET&#xff0c;VCL&#xff0c;COM&#xff0c;ActiveX应用程序添加报表支持&#xff0c;由于其独特的编程原则&#xff0c;现在已经成为了Delphi平台最优秀的报表控件&#xff0c;支持将编程开…

视频批量剪辑:如何给视频添加上下黑边并压缩视频容量。

视频太多了&#xff0c;要如何进行给视频添加上下黑边并压缩视频容量&#xff1f;今天就由小编来教教大家要如何进行操作&#xff0c;感兴趣的小伙伴们可以来看看。 首先&#xff0c;我们要进入视频剪辑高手主页面&#xff0c;并在上方板块栏里选择“批量剪辑视频”板块&#…

PX4无人机调参

文章目录 前言一、滤波参数二、PID参数自动调参手动调参角速率环姿态环 前言 PX4 1.13.2 日志分析软件&#xff1a;flight review https://logs.px4.io/ 一、滤波参数 调参时可以用自稳模式飞行 在调滤波器参数之前&#xff0c;可以先大致调一下PID的参数&#xff0c;角度率…

4-log打印

1.相关文件 2.示例 #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include "nrf.h" #include "nrf_delay.h" #include "app_error.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" …

WPF教程(九)--数据绑定(2)--绑定模式

一、绑定模式 绑定模式以及模式的使用效果。 示例如下是根据ListBox中的选中项&#xff0c;去改变TextBlock的背景色。将 TextBlock 的背景色绑定到在 ListBox 中选择的颜色。在下面的代码中针对TextBlock的 Background 属性使用绑定语法绑定从 ListBox 中选择的值。代码如下。…

typeScript的安装及基础使用示例

4.1.安装typescript npm 包&#xff1a; npm install -g typescript 2.查看安装好的版本检验&#xff1a; tsc -v 3.编译一个typescript 文件&#xff1a;tsc hello.ts 4.运行一个ts文件&#xff1a; 首先安装ts-node &#xff0c;ts-node需要在全局去安装。这里要用 npm…

【LeetCode】剑指 Offer 64. 求1+2+…+n p307 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/qiu-12n-lcof/ 1. 题目介绍&#xff08;64. 求12…n&#xff09; 求 12...n &#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C&#xff09;。 【测试用例】&a…

android aidl

本文只是记录个人学习aidl的实现&#xff0c;如需学习请参考下面两篇教程 官方文档介绍Android 接口定义语言 (AIDL) | Android 开发者 | Android Developers 本文参考文档Android进阶——AIDL详解_android aidl_Yawn__的博客-CSDN博客 AIDL定义&#xff1a;Android 接口…

实验五 视图与完整性约束

实验五 视图与完整性约束 目录 实验五 视图与完整性约束选择题sql评测题1、SQl视图&#xff1a;建立视图CJ\_STUDENT题目代码题解 2、SQL视图&#xff1a;建立视图AVG\_CJ题目代码 3、SQL视图&#xff1a;建立视图IS\_STUDENT题目代码题解 4、SQL视图&#xff1a;根据视图CJ\_S…

pcle接口详解用途说明

PCIE (peripheral component interconnect express) 中文名&#xff1a;高速串行计算机扩展总线标准&#xff0c;它原来的名称为“3GIO”&#xff0c;由英特尔在2001年提出。 PCIE 有 12345代 和x1/x4/x8/x16插槽 1、PCIE x1/x4/x8/x16插槽模式&#xff0c;的区别和用处 pcel …

ChatGPT 下我的焦虑

鉴于一些读者还未体验过&#xff0c;可以看一下以下 GitHub 项目&#xff0c;收集了几千个封装的 ChatGPT 网站&#xff1a; https://github.com/weekend-project-space/chatgpt-sites 在 ChatGPT 刚出的时候&#xff0c;我对 AI 不屑一顾&#xff0c;大概源自于好几年前人工智…

微服务之异步消息通信

Informal Essay By English I’m sorry that I haven’t updated the article lately because the blogger has been busy with interviews and summarizing their experience. I will create a special article to describe the recent events. Next, let’s get to the topi…

FRP 内网穿透,绕过防火墙控制内网机器

内网穿透&#xff0c;端口映射技术是一门十分古老的技术&#xff0c;他一直是一把双刃剑&#xff0c;可以绕过防火墙入侵目标服务器&#xff0c;也可以方便我们运维&#xff0c;工作。 早年的lcx 或者portmap都是比较老的工具了&#xff0c;frp这个工具比之前的lcx或者portmap都…

element-china-area-data 中国省市区级联选择器

1.安装 npm install element-china-area-data -S 2. 说明 文档&#xff1a;element-china-area-data - npm provinceAndCityData是省市二级联动数据&#xff08;不带“全部”选项&#xff09; regionData是省市区三级联动数据&#xff08;不带“全部”选项&#xff09; prov…

车载操作系统架构研究报告

目 录 前 言 ............................................... 1 1 术语定义及缩略语 ................................................................ 3 1.1 术语与定义 ................................................................. 3 1.2 缩略语 ..............…

[读书笔记] Variational AutoEncoders

小全读书笔记 《Variational AutoEncoders》 1. Generative Model &#xff08;生成式模型&#xff09;简述2. 简单生成模型 AutoEncoders![AutoEncoder结构图](https://img-blog.csdnimg.cn/46c5dcf47e754bf7b71d973a15507e0e.png#pic_center)2.1 结构2.2 不足 3. Variational…

【Vue已解决】阻止Vue在启动时生成生产提示

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

3 redis线程IO模型

1 IO模型 1.1 IO IO (Input/Output&#xff0c;输入/输出)即数据的读取&#xff08;接收&#xff09;或写入&#xff08;发送&#xff09;操作&#xff0c;通常用户进程中的一个完整IO分为两阶段&#xff1a;用户进程空间<–>内核空间、内核空间<–>设备空间&…