动态规划练习第一天

动态规划:
要点:

  1. 找到动态转移方程
  2. 找到base case 初始条件

优化方向:空间优化,关注前两个值即可,用两个变量代替。

零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
示例 3:
输入:coins = [1], amount = 0
输出:0


 public static int coinChange2(int[] coins, int amount) {
        //参数判断
        if (coins.length <= 0) {
            return -1;
        }
        //dp数组:存储amount从0到11时需要的硬币数量
        int[] memo = new int[amount + 1];
        //base case 0元时值为0
        memo[0] = 0;
        //遍历从amount = 1开始遍历,结果放入dp数组
        for (int i = 1; i <= amount; i++) {
            //遍历 amount 减去已有的不同数值时 读取dp存储的需要的硬币数量
            int min = Integer.MAX_VALUE;
            for (int coin : coins) {
                //减去coin的值剩余钱数
                int left = i - coin;
                if (left >= 0 && memo[left] < min) {
                    //需要的数量为存储数量+ 1(当前数值硬币)
                    min = memo[left] + 1;
                }
            }
            memo[i] = min;
        }
        return memo[amount] == Integer.MAX_VALUE ? -1 : memo[amount];
    }

使用最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。

  • 支付 15 ,向上爬两个台阶,到达楼梯顶部。
    总花费为 15 。
    示例 2:
    输入:cost = [1,100,1,1,1,100,1,1,100,1]
    输出:6
    解释:你将从下标为 0 的台阶开始。
  • 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
  • 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
  • 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
  • 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
  • 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
  • 支付 1 ,向上爬一个台阶,到达楼梯顶部。
    总花费为 6 。
public int minCostClimbingStairs2(int[] cost) {
        int size = cost.length;
        //dp
        int[] dp = new int[size];
        //base case
        dp[0] = 0;
        dp[1] = Math.min(cost[0], cost[1]);
        for (int i = 2; i < size; i++) {
            dp[i] = Math.min(dp[i-2] + cost[i-1], dp[i-1] + cost[i]);
        }
        return dp[size-1];
    }

连续天数的最高销售额

某公司每日销售额记于整数数组 sales,请返回所有 连续 一或多天销售额总和的最大值。要求实现时间复杂度为 O(n) 的算法。
示例 1:
输入:sales = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:[4,-1,2,1] 此连续四天的销售总额最高,为 6。
示例 2:
输入:sales = [5,4,-1,7,8]
输出:23
解释:[5,4,-1,7,8] 此连续五天的销售总额最高,为 23。

/**
 * 动态规划解析:
 * 状态定义: 设动态规划列表 dp ,dp[i] 代表以元素 sales[i] 为结尾的连续子数组最大和。
 * 转移方程: 若 dp[i−1]≤0,说明 dp[i−1] 对 dp[i] 产生负贡献,
 * 即 dp[i−1]+sales[i]还不如 sales[i]本身大。
 * <p>
 * dp[i] = dp[i−1] + sales[i],  dp[i−1]>0
 * dp[i] = sales[i],         dp[i−1]≤0
 * 初始状态: dp[0]=sales[0],即以 sales[0] 结尾的连续子数组最大和为 sales[0]
 * 返回值: 返回 dp 列表中的最大值,代表全局最大值。
 * 空间优化:
 * 由于 dp[i]只与 dp[i−1] 和 sales[i] 有关系,因此可以将原数组 sales 用作 dp 列表,即直接在 sales上修改即可。
 * 由于省去 dp 列表使用的额外空间,因此空间复杂度从 O(N) 降至 O(1)。
 * [5,4,-1,7,8]
 * [0,5,9,8,15,23]
 * [-2,1,-3,4,-1,2,1,-5,4]
 * [0,]
 */
public static int maxSales(int[] sales) {
    //初始状态
    int res = sales[0];
    for (int i = 1; i < sales.length; i++) {
        //状态转移方程
        //dp[i] = dp[i−1] + sales[i],  dp[i−1]>0
        //dp[i] = sales[i],         dp[i−1]≤0
        int max = Math.max(sales[i - 1], 0);
        sales[i] += max;
        res = Math.max(res, sales[i]);
    }
    return res;
}

连续数列

给定一个整数数组,找出总和最大的连续数列,并返回总和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

public int maxSubArray(int[] nums) {

    int res = nums[0];

    for (int i = 1; i < nums.length; i++) {
        int max = Math.max(nums[i - 1], 0);
        nums[i] = nums[i] + max;
        res = Math.max(nums[i], res);
    }
    return res;
}

按摩师

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间, 因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
示例 3:
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。

/**
 * dp[i][0] 考虑前i个预约,第i个预约不接的最长预约时间
 * dp[i][1] 考虑前i个预约,第i个预约接的最长预约时间
 * 从前往后计算,已计算出前i-1个dp值,考虑计算dp[i][0/1]的答案
 * 转移方程
 *   dp[i][0] 第i个状态不接, 第i-1个预约接不接都可以,考虑dp[i-1][0] 和dp[i-1][1] 两个状态转移过来 dp[i][0] = max(dp[i-1][0],dp[i-1][1])
 *   dp[i][1] 第i个状态接,  第i-1个预约不接,从dp[i-1][0]状态转移 转移方程:dp[i][1] = dp[i-1][0] + numsi  (numsi表示第i个预约的时长)
 * 答案取 max(dp[n][0], dp[n][1]) ,n表示预约的个数
 *
 * 优化:计算dp[i][0/1] 时,只与前一个状态dp[i-1][0/1]有关,可以不用开数组,只用两个变量dp0和dp1 分别存储dp[i-1][0] 和dp[i-1][1]
 *
 * */
public static int massage(int[] nums) {
    int n = nums.length;
    if (n == 0) {
        return 0;
    }
    //两个变量,分别存储dp[i-1][0] 和dp[i-1][1]
    int dp0 = 0, dp1 = nums[0];

    for (int i = 1; i < n; ++i){
        //计算第i个不接的情况,考虑i-1接与不接两种情况
        int tdp0 = Math.max(dp0, dp1); // 计算 dp[i][0]
        //计算第i个接的情况,第i-1个只能不接
        int tdp1 = dp0 + nums[i]; // 计算 dp[i][1]

        dp0 = tdp0; // 用 dp[i][0] 更新 dp_0
        dp1 = tdp1; // 用 dp[i][1] 更新 dp_1
    }
    return Math.max(dp0, dp1);
}

三步问题

有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
示例1:
输入:n = 3
输出:4
说明: 有四种走法
示例2:
输入:n = 5
输出:13
提示:
n范围在[1, 1000000]之间
三种情况:
(1)剩余一层楼梯要走然后一步走一层
(2)剩余两层楼梯要走,然后一步走两层
(3)剩余三层楼梯要走,然后一步走三层
dp[n] = dp[n-1] + dp[n-2] + dp[n-3]

public int waysToStep(int n) {
    if (n <= 2) {
        return n;
    }
    int[] dp = new int[n+1];
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 4;
    for (int i = 4; i < n+1; i++) {
        dp[i] = (dp[i-1] + (dp[i-2] + dp[i-3]) % 1000000007) % 1000000007;
    }
    return dp[n];
}

跳跃训练

今天的有氧运动训练内容是在一个长条形的平台上跳跃。台有 num 个小格子,每次可以选择跳 一个格子 或者 两个格子。请返回在训练过程中,学员们共有多少种不同的跳跃方式。结果可能过大,因此结果需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 5
输出:8

public int trainWays(int num) {

    if(num == 0){
        return 0;
    }
    if (num <=2) {
        return num;
    }

    int[] dp = new int[num + 1];

    dp[1] = 1;
    dp[2] = 2;
    for (int i = 3; i < num + 1; i++) {
        dp[i] = (dp[i-1] + dp[i-2]) % 1000000007;
    }
    return dp[num];
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 设计模式系列:行为型-状态模式

简介 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;允许一个对象在其内部状态改变时改变其行为。状态模式中类的行为是由状态决定的&#xff0c;在不同的状态下有不同的行为。 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂…

智能合约语言(eDSL)—— 使用rust实现eDSL的原理

为理解rust变成eDSL的实现原理&#xff0c;我们需要简单了解元编程与宏的概念,元编程被描述成一种计算机程序可以将代码看待成数据的能力&#xff0c;使用元编程技术编写的程序能够像普通程序在运行时更新、替换变量那样操作更新、替换代码。宏在 Rust 语言中是一种功能&#x…

鸿蒙开发实战:【系统服务管理部件】

简介 samgr组件是OpenHarmony的核心组件&#xff0c;提供OpenHarmony系统服务启动、注册、查询等功能。 系统架构 图 1 系统服务管理系统架构图 目录 /foundation/systemabilitymgr ├── samgr │ ├── bundle.json # 部件描述及编译文件 │ ├── frameworks …

多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

基于springboot+vue的智慧生活商城系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Stability AI 3D:开创3D视觉技术新篇章,提升多视角连贯性与生成质量

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

杰发科技AC7801——Flash数据读取

0. 简介 因为需要对Flash做CRC校验&#xff0c;第一步先把flash数据读出来。 1. 代码 代码如下所示 #include "ac780x_eflash.h" #include "string.h" #define TestSize 1024 ///< 4K #define TestAddressStart 0x08000000 uint8_t Data[7000]; int…

【NLP笔记】Transformer

文章目录 基本架构EmbeddingEncoderself-attentionMulti-Attention残差连接LayerNorm DecoderMask&Cross Attention线性层&softmax损失函数 论文链接&#xff1a; Attention Is All You Need 参考文章&#xff1a; 【NLP】《Attention Is All You Need》的阅读笔记 一…

多数据源 - dynamic-datasource | 集成 HikariCP 连接池

文章目录 连接池集成简介HikariCP 连接池默认 HikariCP 配置自定义 HikariCP 配置Druid 连接池BeeCp 连接池DBCP2 连接池JNDI 数据源🗯️ 上节回顾:上一节中,实现了 dynamic-datasource 的快速入门。 👉 本节目标:在上一节的基础上,集成 HikariCP 数据库连接池并介绍原…

es 集群安全认证

参考文档&#xff1a;Configure security for the Elastic Stack | Elasticsearch Guide [7.17] | Elastic ES敏感信息泄露的原因 Elasticsearch在默认安装后&#xff0c;不提供任何形式的安全防护不合理的配置导致公网可以访问ES集群。比如在elasticsearch.yml文件中,server…

【SpringSecurity】十三、基于Session实现授权认证

文章目录 1、基于session的认证2、Demosession实现认证session实现授权 1、基于session的认证 流程&#xff1a; 用户认证成功后&#xff0c;服务端生成用户数据保存在session中服务端返回给客户端session id (sid&#xff09;&#xff0c;被客户端存到自己的cookie中客户端下…

C# 使用OpenCvSharp4将Bitmap合成为MP4视频的环境

环境安装步骤&#xff1a; 在VS中选中项目或者解决方案&#xff0c;鼠标右键&#xff0c;选择“管理Nuget包”&#xff0c;在浏览窗口中搜索OpenCVSharp4 1.搜索OpenCvSharp4,选择4.8.0版本&#xff0c;点击安装 2.搜索OpenCvSharp4.runtime.win,选择4.8.0版本&#xff0c;点…

O2OA红头文件流转与O2OA版式公文编辑器基本使用

O2OA开发平台在流程管理中&#xff0c;提供了符合国家党政机关公文格式标准&#xff08;GB/T 9704—2012&#xff09;的公文编辑组件&#xff0c;可以让用户在包含公文管理的项目实施过程中&#xff0c;轻松地实现标准化公文格式的在线编辑、痕迹保留、手写签批等功能。并且可以…

vue-router(v4.0) 基础3

编程式导航 除了使用 <router-link> 创建 a 标签来定义导航链接&#xff0c;我们还可以借助 router 的实例方法&#xff0c;通过编写代码来实现。导航到不同的位置 示例该方法的参数可以是一个字符串路径&#xff0c;或者一个描述地址的对象。例如&#xff1a; // 字符串…

Panasonic松下PLC如何数据采集?如何实现快速接入IIOT云平台?

在工业自动化领域&#xff0c;数据采集与远程控制是提升生产效率、优化资源配置的关键环节。对于使用Panasonic松下PLC的用户来说&#xff0c;如何实现高效、稳定的数据采集&#xff0c;并快速接入IIOT云平台&#xff0c;是摆在他们面前的重要课题。HiWoo Box工业物联网关以其强…

fs方法举例

fs.readFile() 读取文件 const fs require(node:fs) const path require(node:path) const s path.resolve(__dirname, ./hello.txt) const buf fs.readFileSync(s) console.log(buf.toString())输出的Buffer对象 用toString()方法转字符串之后 fs.appendFile() 创建新…

景联文科技:提供通用多模态数据,助力AI多模态领域实现飞跃式发展

回顾2023年&#xff0c;以ChatGPT为代表的通用人工智能大模型在全球范围内掀起了新一轮人工智能产业发展浪潮&#xff0c;我国人工智能大模型市场呈现百“模”争鸣、日新月异的迅猛发展态势。 根据大模型之家、钛媒体数据&#xff0c;2023年中国大模型市场规模达到147亿人民币&…

CMU 10-414/714: Deep Learning Systems --hw3

实现功能 在ndarray.py文件中完成一些python array操作 我们实现的NDArray底层存储就是一个一维向量&#xff0c;只不过会有一些额外的属性&#xff08;如shape、strides&#xff09;来表明这个flat array在维度上的分布。底层运算&#xff08;如加法、矩阵乘法&#xff09;都…

《优化接口设计的思路》系列:第九篇—用好缓存,让你的接口速度飞起来

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 作为一名从业已达六年的老码农&#xff0c…

Android14音频进阶:AudioFlinger究竟如何混音?(六十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…
最新文章