算法设计思想——动态规划

这篇具有很好参考价值的文章主要介绍了算法设计思想——动态规划。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

动态规划(Dynamic Programming,简称DP)

是一种常见的算法设计方法,用于解决一类重叠子问题的优化问题。他的基本思想是将问题分解成多个重叠的子问题,递归求解,并将子问题的求解缓存起来,避免重复计算,从而得到问题的解。

动态规划通常适用于以下两个条件的问题:
1.重叠子问题:原问题可以分解为若干个子问题,子问题之间存在重叠部分,即某些问题的解在求解过程中被多次引用。

2.最优子结构:原问题的最优解可以由子问题的最优解推导得到,即原问题的最优解包含子问题的最优解。

动态规划算法的基本步骤如下:

  1. 定义状态:将原问题划分为若干个子问题,并定义状态表示子问题的解。
  2. 定义状态转移方程:根据子问题之间的关系,建立子问题之间的递推关系式,即状态转移方程。
  3. 初始化状态:确定初始化的值,即最简单的子问题的解。
  4. 计算状态:按照状态转移方程,从简单的子问题开始递推,计算出所有子问题的解。
  5. 求解原问题:根据子问题的解,求出原问题的解 。

动态规划算法的时间复杂度通常为或,取决于问题的规模和状态转移方程的复杂度。

下面来看例题:

假设你正在爬楼梯。需要n阶你才能到达楼顶。

每次你可以爬 1或 2 个台阶。那么一共有多少种不同的方法可以爬到楼顶呢?

下面以动态规划五部曲原则来进行构思:

  1. 定义状态:需要定义一个一维数组来记录不同楼层的状态,因此我们需要——确定St数组以及下标的含义        St[i]:爬到第i层,有St[i]种方法
  2. 确定递推公式:首先如果是 st[i-1],上 i-1 层楼梯,有 st[i-1] 种方法,那么再一步跳一个台阶就是 St[i];如果是 St[i-2],上 i-2 层楼梯,有 St[i-2] 种方法,那么再跳一步两个台阶就是St[i],于是st[i] = st[i-1] + st[i-2]。
  3. St数组的初始化:我们需要考虑为St为0的情况,按照题干来理解,当楼层为0的时候,我们什么也不用做,于是i就为 0。有一个争议点就是:当St[0]应该为1的理由其实是因为dp[0] =1的话在递推的过程中 i 从 2 开始遍历才能执行下去,实际从题干出发,n是正整数,那么i也应该为为正整数,所以不需要讨论St[0]的初始化,我们直接从dp[1] = 1;dp[2] =2,然后从 i = 3开始递推。
  4. 确定遍历顺序:由递推公式st[i] = st[i-1] + st[i-2]得到,遍历顺序从前向后
  5. 举例推导St数组:当例如,我们n = 6时,st table如下:动态规划的设计思想,算法,动态规划

没错,这其实就是斐波那契数列(Fibonacci sequence),五部曲分析完成后,我们的代码如下:

#include <iostream>
#include <vector>
using namespace std;

class MyMethod {
public:
    int clbStairs(int n){
        if (n == 1) return 1;
        if (n == 2) return 2;
        vector<int> st(n+1);
        st[1] = 1;
        st[2] = 2;
        for (int i = 3; i <= n; i++){
            st[i] = st[i-1] + st[i-2];
        }
        return st[n];
    }
};

int main(){
    int n = 6;
    int ret = MyMethod().clbStairs(n);
    cout << ret << endl;
    return 0;
}

 时间复杂度(time complexity):

空间复杂度(space complexity):

考虑到代码优化的话,我们用sum减少数据结构,使用常量来保存状态,代码如下:

#include <iostream>
#include <vector>
using namespace std;

class MyMethod {
public:
    int clbStairs(int n){
        if (n == 1) return 1;
        if (n == 2) return 2;
        vector<int> st(n+1);
        st[1] = 1;
        st[2] = 2;
        for (int i = 3; i <= n; i++){
            int sum = st[1] + st[2];
            st[1] = st[2];
            st[2] = sum;
        }
        return st[2];
    }
};

int main(){
    int n = 6;
    int ret = MyMethod().clbStairs(n);
    cout << ret << endl;
    return 0;
}

 时间复杂度(time complexity):

空间复杂度(space complexity):

总结

虽然这道题的实质是斐波那契数列,但理解到动态规划的程序设计思路其实没那么轻松,关键是能够迅速捕捉到这一概念,进行建模,按照动态规划五部曲的递推公式,逐步推导得到结果。文章来源地址https://www.toymoban.com/news/detail-775822.html

到了这里,关于算法设计思想——动态规划的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式-01.设计思想

    此系列文章非本人原创,是学习笔记。 下面讲一些常见的设计思想 这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。 如何解读原则中的“接口”二字? “基于接口而非实现编程”这条原则的英文描述是:“Program to an interface, n

    2024年02月07日
    浏览(57)
  • Spring核心设计思想

    目录 前言: Spring是什么 什么是IoC 传统开发思想 IoC开发思想 Spring IoC 什么是DI 小结:     官网中提出:Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world\\\'s most popular Java framework.     Spring 使编程 Java 对每个人来

    2023年04月17日
    浏览(35)
  • 闪电网络协议设计思想剖析

    闪电网络可能是比特币之上部署的最受期待的技术创新。闪电网络,为由 Joseph Poon 和 Tadge Dryja 于2015年首次提出的支付层,承诺支持: 用户之间几乎无限数量的链下交易, 几乎免费, 同时利用比特币提供的安全性。 2016年时,至少三个公司——Poon 和 Dryja 的 Lightning、 Block

    2024年03月20日
    浏览(50)
  • Spring 核心与设计思想

    ✏️作者:银河罐头 📋系列专栏:JavaEE 🌲 “种一棵树最好的时间是十年前,其次是现在” 通常所说的 Spring 指的是 Spring Framework(Spring 框架)。 Spring 是包含多种工具方法的 IoC 容器。 IoC(Inversion of Control): 控制反转 \\\"控制反转\\\"又是什么意思? 下面以一个程序来举例。 假如我

    2024年02月02日
    浏览(40)
  • 【Spring】核心与设计思想

     哈喽,哈喽,大家好~ 我是你们的老朋友: 保护小周ღ   谈起Java 圈子里的框架,最年长最耀眼的莫过于 Spring 框架啦,如今已成为最流行、最广泛使用的Java开发框架之一。不知道大家有没有在使用 Spring 框架的时候思考过这些问题, 什么是框架?Spring 是什么?如何理解

    2024年02月08日
    浏览(29)
  • Spring框架核心与设计思想

    我们一般所说的Spring指的是Spring Framework(Spring 框架),它是一个开源的框架,Spring支持广泛的应用场景,它可以让Java企业级的应用程序开发变得更简单,官方一点的回答:spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级

    2023年04月15日
    浏览(33)
  • 从架构设计思想出发看Flutter

    Flutter 是一种流行的移动应用程序开发框架,它的设计特点之一是可以使用单一代码库构建 iOS 和 Android 应用程序。然而,对于功能比较多、模块比较复杂的应用程序,仅凭单一的代码库就可能导致代码的复杂性和维护难度的增加。在这种情况下,通过合适的应用程序架构设计

    2024年02月07日
    浏览(59)
  • Spring框架概述及核心设计思想

    我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因;Spring 支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更简单。 用⼀句话概括 Spring: Spring 框架是包含了众多工具方法的

    2024年02月16日
    浏览(27)
  • 【JavaEE进阶】 Spring核⼼与设计思想

    我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。 ⽤⼀句话概括 Spring: Spring 是包含了众多⼯具⽅法的 I

    2024年02月04日
    浏览(31)
  • Cola4.0 - DDD 设计思想

    COLA提供了一整套代码架构,拿来即用。 其中包含了很多架构设计思想,包括讨论度很高的领域驱动设计DDD等。 COLA 的分层是一种经过改良的三层架构,主要是讲传统的业务逻辑层拆分为展示层、应用层、领域层和基础设施层。 展示层(Presentation Layer):负责以 Rest 的风格接

    2024年02月08日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包