【动态规划Ⅰ】斐波那契、爬楼梯、杨辉三角

news2024/11/9 9:54:46

动态规划—斐波那契系列

  • 什么是动态规划
  • 斐波那契数组相关题目
    • 509. 斐波那契数 Easy
    • 1137. 第 N 个泰波那契数 Easy
  • 杨辉三角
    • 118. 杨辉三角 Easy
  • 爬楼梯相关题目
    • 70. 爬楼梯 Easy
    • 746. 使用最小花费爬楼梯 Easy

什么是动态规划

动态规划是一种通过将原问题分解为相对简单的子问题来解决复杂问题的方法。基本思想是递归地将一个复杂的问题划分为许多更简单的子问题,存储这些子问题的每个子问题的解,并最终将存储的答案用于解决原始问题。通过缓存子问题的解,动态规划有时可以避免指数级的浪费。它通常用于优化问题,其中需要找到最佳解决方案。动态规划算法通常用于解决具有重叠子问题和最优子结构性质的问题。

  • 重叠子问题:原问题可以被分解为相同的子问题。这意味着在解决原问题时,我们可能多次解决相同的子问题。
  • 最优子结构:问题的最优解可以通过其子问题的最优解来求解。

通常,使用动态规划解决问题的步骤包括以下几个方面:

  • 定义子问题:将原问题分解为子问题。
  • 解决子问题:解决子问题并将结果存储起来,通常使用数组或类似的数据结构来存储子问题的解,以避免重复计算。
  • 合并子问题的解:利用子问题的解构建原问题的解。
  • 递归或迭代:通常使用递归或迭代的方式来解决问题。

斐波那契数组相关题目

斐波那契数组是典型的动态规划问题,可以从存储的子问题答案扩展到要求解的大问题。

509. 斐波那契数 Easy

509. 斐波那契数

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。

其实可以直接用一个数组,dp[i]就对应F(i),但实际上我们并不需要整个数组,只需要F(n),而F(n)只和F(n-1)和F(n-2)相关,因此直接用两个变量存储即可。更新过程就是F(n) = F(n - 1) + F(n - 2)。Java代码如下:

class Solution {
    public int fib(int n) {
        if(n <= 1)
            return n;
        int f0 =0, f1 = 1;
        for(int i = 2; i <= n; i++){
            int cur = f0 + f1;
            f0 = f1;
            f1 = cur;
        }
        return f1;
    }
}

1137. 第 N 个泰波那契数 Easy

1137. 第 N 个泰波那契数

泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

这个和上面的斐波那契基本一样,只是当前状态由前面三个状态决定,而不是前面两个。用三个变量分别存储Tn、Tn+1、Tn+2,按照 Tn+3 = Tn + Tn+1 + Tn+2逐步更新即可。 Java代码如下:

    public int tribonacci(int n) {
        if(n <= 1)
            return n;
        if (n == 2)
            return 1;
        
        int f0 = 0, f1 = 1, f2 = 1;
        for(int i = 3; i <= n; i++){
            int cur = f0 + f1 + f2;
            f0 = f1;
            f1 = f2;
            f2 = cur;
        }
        return f2;
    }
}

杨辉三角

118. 杨辉三角 Easy

118. 杨辉三角

给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
在这里插入图片描述

其实斐波那契和杨辉三角,都是数学里面学过的,更新过程已经很清晰了。 上面的图这个三角形,如果变成数组左下角直角的形式,对于每一行,dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。Java代码如下:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> triangle = new ArrayList<>();   
        for(int i = 0; i < numRows; i++){
            List<Integer> newRow = new ArrayList<>();            
            for(int j = 0; j <= i; j++){
                if(j==0 || j==i)
                    newRow.add(1);
                else
                    newRow.add(triangle.get(i-1).get(j) + triangle.get(i-1).get(j-1));
            }           
            triangle.add(newRow);
        }
        return triangle;        
    }
}

爬楼梯相关题目

70. 爬楼梯 Easy

70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

根据题目,到第n阶台阶,可以从n-1跨一步到;可以从n-2跨两步到。因此动态规划的状态转移:dp[n] = dp[n-1] + dp[n-2]。实际上只需要存储dp[n-1]和dp[n-2]这两个变量即可。Java代码如下:

class Solution {
    public int climbStairs(int n) {
        if(n <=2 )
            return n;
        int stair1 =1, stair2 = 2;
        for(int i = 3; i <= n; i++){
            int cur = stair1 + stair2;
            stair1 = stair2;
            stair2 = cur;
        }
        return stair2;    
    }
}

746. 使用最小花费爬楼梯 Easy

746. 使用最小花费爬楼梯

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

上一个题目是直接求方法总和,这个题目是最小最大问题。 但本质上两个题一样的,因此到当前第i个台阶的代价,取决与i-1和i-2。因为在i-1个台阶上付出cost[i-1]的费用,选择向上一个台阶就到了第i阶;同样在第i-2个台阶上付出cost[i-2]的费用,选择向上两个台阶就到了第i个台阶。因为是最小值,因此dp[i] = min(dp[i-2] + cost[i-2], dp[i-1] + cost[i-1])。由于只和dp[i-1]、dp[i-2]两个状态相关,因此可以优化成只用两个变量存储,Java代码如下:

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        if(n == 2)
            return Math.min(cost[0],cost[1]);
        int minCost1 = 0, minCost2 = 0;
        for(int i = 2; i <= n ; i++){
            int newCost = Math.min(minCost1 + cost[i-2], minCost2 + cost[i-1]);
            minCost1 = minCost2;
            minCost2 = newCost;
        }
        return minCost2;
    }
}

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

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

相关文章

【代码规范】.train(False)和.eval()的相似性和区别

【代码规范】.train(False)和.eval()的相似性和区别 文章目录 一、.train(False) 和 .eval() 的功能二、.train(False) 和 .eval() 的区别2.1 .eval()2.2 .train(False)2.3 总结 三、.eval()更加规范 一、.train(False) 和 .eval() 的功能 .train(False) 和 .eval() 在功能上非…

STM32CubeMX配置STM32G071输入捕获(HAL库开发)

1.时钟配置HSI主频配置64M 2.配置好串口&#xff0c;选择异步模式 3.配置TIM1_CH1产生1KHz的信号&#xff0c;主频64MHz&#xff0c;分频&#xff08;64-1&#xff09;&#xff0c;计数周期&#xff08;1000-1&#xff09;&#xff0c;这样即可生成1KHz信号。 4.配置TIM3_CH1和…

Linux 07:基础IO

stdin & stdout & stderr C默认会打开三个输入输出流&#xff0c;分别是stdin, stdout, stderr。仔细观察发现&#xff0c;这三个流的类型都是FILE*, fopen返回值类型&#xff0c;文件指针。 文件读取函数&#xff08;库函数&#xff09;&#xff1a; fopen、fread、…

2024 年你需要知道的免费 API-独立产品灵感周刊 DecoHack #061

本周刊记录有趣好玩的独立产品设计开发相关内容&#xff0c;每周发布&#xff0c;往期内容同样精彩&#xff0c;感兴趣的伙伴可以 点击订阅我的周刊。为保证每期都能收到&#xff0c;建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。 &#x1f4bb; 产品推荐 1. Pintree 首先…

01- 收入数据集【Pytorch入门实战】

目录 一、机器学习基础 二、实战例子 1.数据集分析 2.实战训练 3.总结 三、参考资料 一、机器学习基础 为了解决这个问题&#xff0c;人们想到数据驱动方法&#xff0c;也就是让计算机从现有的大量的带标签图片电学习规律&#xff0c;一旦计算机学习到了其中的规律&…

【绝命Coding助力秋招】Python实现<实习僧>海投脚本

hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;绝命Coding-CSDN博客 &a…

异常、File

异常、File 异常 异常就是代表程序出现的问题 Error&#xff1a;代表的系统级别错误&#xff08;属于严重问题&#xff09;。系统一旦出现问题&#xff0c;sun公司会把这些错误封装成Error对象。Error是给sun公司自己用&#xff0c;不是给我们程序员用的。因此我们开发人员不…

SpringCloud--常用组件和服务中心

常用组件 Euroke和nacos 区别 负载均衡 负载均衡策略有哪些 自定义负载均衡策略

AV1 编码标准中帧内预测技术概述

AV1 编码标准帧内预测 AV1&#xff08;AOMedia Video 1&#xff09;是一种开源的视频编码格式&#xff0c;旨在提供比现有标准更高的压缩效率和更好的视频质量。在帧内预测方面&#xff0c;AV1相较于其前身VP9和其他编解码标准&#xff0c;如H.264/AVC和H.265/HEVC&#xff0c;…

自建文件分享平台Pingvin Share系统

Pingvin Share可以用来代替 WeTransfer 等的分享网站&#xff0c;如果你有自己的服务器&#xff0c;可以支持通过 Docker 部署或者 Stand-alone 部署。 功能介绍 完全自建&#xff1a;轻松使用私有服务器搭建文件共享平台 完全隐私&#xff1a;你的文件只属于你&#xff01;不…

相交链表+判断环型链表+求环型链表的入口节点

链表OJ题 一.相交链表二.判断环型链表三.求环型链表的入口节点 一.相交链表 相交链表 相交&#xff1a;两个链表从头开始遍历&#xff0c;尾节点一定是同一个节点。 情况一&#xff1a;当两个链表长度相同时&#xff1a; 情况二&#xff1a;当两个链表长度不同时&#xff1…

【详解】Spring Cloud概述

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1. 认识微服务 1.1 单体架构 1.2 集群和分布式架构 1.3 集群和分布式…

如何利用windows本机调用Linux服务器,以及如何调用jupyter界面远程操控

其实这篇文章没必要存在&#xff0c;教程太多了 参考博客&#xff08;1 2 3&#xff09;&#xff0c;如侵删 奈何网上的大神总是会漏掉一些凡人遇到的小问题 &#xff08;1&#xff09; 建议下载PuTTy for windows&#xff0c;从而建立与远程服务器的SSH连接 需要确认目标服…

nodejs安装部署运行vue前端项目

文章目录 1.安装nodejs2.安装Vue CLI1.配置npm镜像源&#xff1a;2.安装Vue CLI&#xff1a;3.创建Vue项目4.启动Vue项目5.Express 1.安装nodejs Node.js 是一个免费、开源、跨平台的 JavaScript 运行时环境&#xff0c;它让开发人员能够创建服务器、Web 应用、命令行工具和脚…

【C++PythonJava】字符处理详细解读_字符_ASCLL码_字母数字转换_算法竞赛_开发语言

文章目录 Beginning1&#xff09;ASCLL 码2&#xff09;大小比较2&#xff09;判断数字字符3&#xff09;字符、数字间的相互转换End Beginning 在 C 中&#xff0c;字符和整数有着密不可分的关系。原因就是在计算机中&#xff0c;字符是以一种较 ASCLL 码的整数存储的。自然&…

SpringSecurity框架【认证】

目录 一. 快速入门 二. 认证 2.1 登陆校验流程 2.2 原理初探 2.3 解决问题 2.3.1 思路分析 2.3.2 准备工作 2.3.3 实现 2.3.3.1 数据库校验用户 2.3.3.2 密码加密存储 2.3.3.3 登录接口 2.3.3.4 认证过滤器 2.3.3.5 退出登录 Spring Security是Spring家族中的一个…

C语言之qsort函数

一、qsort 1.库函数qsort qsort是库函数&#xff0c;直接可以用来排序数据&#xff0c;底层使用的是快速排序。 qsort函数可以排序任意类型的数据。 2.头文件 #include<stdlib.h> 3.参数讲解 void*类型的指针是无具体类型的指针&#xff0c;这种类型的指针的不能直接解…

Still-Moving效果惊艳!无需定制视频数据,DeepMind让文生定制视频变得简单!

文章链接&#xff1a; https://arxiv.org/pdf/2407.08674 github链接&#xff1a; https://still-moving.github.io/ Still-Moving 自定义文本生成图像&#xff08;T2I&#xff09;模型最近取得了巨大进展&#xff0c;尤其是在个性化、风格化和条件生成等领域。然而&#xff0c…

星辰计划02-独特视角的spring动态代理

承接上一文 动态代理 &#xff0c;这里探究spring 动态代理 会话1&#xff1a;spring动态代理 quick start &#x1f467;哥哥&#xff0c;哥哥&#xff0c;spring 怎么去搞动态代理的呢&#x1f468; 来来来&#xff0c;听我细细来说 quick start通过Spring的 ProxyFactory…

学习小记-Nacos的服务注册与发现原理

服务注册&#xff1a; 当一个服务实例启动时&#xff0c;它会向 Nacos 服务器注册自己的信息&#xff0c;包括 IP 地址、端口号、元数据&#xff08;如服务版本、区域信息等&#xff09;。服务实例使用 Nacos API 发送注册请求&#xff0c;Nacos 服务器接收请求并存储服务实例信…