动态规划c++

1. 什么是动态规划动态规划

(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

1.1 重叠子问题与最优子结构

1.1.1 重叠子问题

重叠子问题是指在问题的求解过程中,存在多次使用相同的子问题的情况,即在求解问题的不同阶段,需要求解的子问题可能是相同的。重叠子问题是动态规划算法设计的基础之一,利用子问题的重叠性可以减少重复计算,提高算法效率。

1.1.2 最优子结构

最优子结构是指问题的最优解可以通过子问题的最优解来构造得到。也就是说,问题的最优解包含子问题的最优解。通俗地说,就是大问题的最优解可以由小问题的最优解推出。这是动态规划的关键性质之一。

1.1.3 举例

举个例子,假设有一个包含n个元素的序列,需要找出其中的最长递增子序列(LIS,Longest Increasing Subsequence)。这个问题就具有最优子结构性质。如果一个序列的LIS已知,那么如果在其末尾添加一个元素,就有两种情况:

1.如果该元素大于当前LIS的末尾元素,那么新序列的LIS为当前LIS加上这个元素,长度为原序列的LIS长度加1;
2.如果该元素小于等于当前LIS的末尾元素,那么当前LIS不会受到影响,新序列的LIS仍然是原序列的LIS。

因此,该问题的最优解可以通过已知的子问题的最优解构造得到。

1.2 动态规划的核心思想

动态规划最核心的思想,就在于拆分子问题,记住过往,减少重复计算。

我们来看下,网上比较流行的一个例子:

A : "1+1+1+1+1+1+1+1 =?"
A : "上面等式的值是多少"
B : 计算 "8"
A : 在上面等式的左边写上 "1+" 呢?
A : "此时等式的值为多少"
B : 很快得出答案 "9"
A : "你怎么这么快就知道答案了"
A : "只要在8的基础上加1就行了"
A : "所以你不用重新计算,因为你记住了第一个等式的值为8!动态规划算法也可以说是 '记住求过的解来节省时间'"

1.3 从青蛙跳台阶进入动态规划

leetcode原题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法

1.3.1 解题思路

基本思想:动态规划从较小问题的解,由交叠性质,逐步决策出较大问题的解,它是从f(1)往f(10)方向,往上推求解,所以称为自底向上的解法。

什么意思,我们从第一个台阶往上推,假设跳到第n级台阶的跳数我们定义为f(n):

1.当只有1级台阶时,只有一种跳法,即f(1)= 1;
2.当只有2级台阶时,有两种跳法。第一种是直接跳两级。第二种是先跳一级,然后再跳一级。即f(2) = 2;
3.当有3级台阶时,也有两种跳法。第一种是从第1级台阶直接跳两级。第二种是从第2级台阶跳一级。即f(3) = f(1) + f(2);
4.要想跳到第4级台阶,要么是先跳到第3级,然后再跳1级台阶上去;要么是先跳到第2级,然后一次迈2级台阶上去。即f(4) = f(2) + f(3);

此时,我门就能得到公式:

f(1) = 1;
f(2) = 2;
f(3) = f(1) + f(2);
f(4) = f(2) + f(3);

f(10) = f(8) + f(9);
即f(n) = f(n - 2) + f(n - 1)。

此时我们来看看动态规划的典型特征在此题中的展现:

1.最优子结构:f(n-1)和f(n-2) 称为 f(n) 的最优子结构。
2.重叠子问题:比如f(10)= f(9)+f(8),f(9) = f(8) + f(7) ,f(8)就是重叠子问题。
3.状态转移方程:f(n)= f(n-1)+f(n-2)就称为状态转移方程。
4.边界:f(1) = 1, f(2) = 2 就是边界。

1.3.2 代码

代码思路如图:


代码实现:

class Solution {
public:
    int numWays(int n) {
        int dp[101] = {0};
        int mod = 1000000007;

        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
            dp[i] %= mod;
        }

        return dp[n] % mod;
    }
};


这个方法空间复杂度是O(n),但是呢,仔细观察上图,可以发现,f(n)只依赖前面两个数,所以只需要两个变量a和b来存储,就可以满足需求了,因此空间复杂度是O(1)就可以啦。


代码实现:

class Solution {
public:
    int numWays(int n) {
        if (n < 2) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        int a = 1;
        int b = 2;
        int temp = 0;
        for (int i = 3; i <= n; i++) {
            temp = (a + b)% 1000000007;
            a = b;
            b = temp;
        }
        return temp;
    }
};


2. 动态规划解题套路

2.1 核心思想

动态规划的核心思想就是拆分子问题,记住过往,减少重复计算。 并且动态规划一般都是自底向上的,因此到这里,基于青蛙跳阶问题,总结了一下做动态规划的思路:

1.穷举分析
2.确定边界
3.找出规律,确定最优子结构
4.写出状态转移方程

2.1.1按例分析

1.穷举分析
(1)当台阶数是1的时候,有一种跳法,f(1) =1)
(2)当只有2级台阶时,有两种跳法,第一种是直接跳两级,第二种是先跳一级,然后再跳一级。即f(2) = 2;
(3)当台阶是3级时,想跳到第3级台阶,要么是先跳到第2级,然后再跳1级台阶上去,要么是先跳到第 1级,然后一次迈 2 级台阶上去。所以f(3) = f(2) + f(1) =3
(4)当台阶是4级时,想跳到第3级台阶,要么是先跳到第3级,然后再跳1级台阶上去,要么是先跳到第 2级,然后一次迈 2 级台阶上去。所以f(4) = f(3) + f(2) =5
(5)当台阶是5级时…

2.确定边界
通过穷举分析,我们发现,当台阶数是1的时候或者2的时候,可以明确知道青蛙跳法。f(1) =1,f(2) = 2,当台阶n>=3时,已经呈现出规律f(3) = f(2) + f(1) =3,因此f(1) =1,f(2) = 2就是青蛙跳阶的边界。

3.找规律,确定最优子结构
n>=3时,已经呈现出规律 f(n) = f(n-1) + f(n-2) ,因此,f(n-1)和f(n-2) 称为 f(n) 的最优子结构。什么是最优子结构?有这么一个解释:

一道动态规划问题,其实就是一个递推问题。假设当前决策结果是f(n),则最优子结构就是要让 f(n-k) 最优,最优子结构性质就是能让转移到n的状态是最优的,并且与后面的决策没有关系,即让后面的决策安心地使用前面的局部最优解的一种性质

4.通过前面3步,穷举分析,确定边界,最优子结构,我们就可以得出状态转移方程啦:


3. 例题

3.1 递增子序列

3.1.1. 穷举分析:

1.当nums只有10的时候,最长子序列[10],长度1。
2.当nums加入9时,最长子序列[10]或[9],长度1。
3.当nums加入2时,最长子序列[10]或[9]或[2],长度1。
4.当nums加入5时,最长子序列[2, 5],长度2。
5.当nums加入3时,最长子序列[2, 5]或[2, 3],长度2。
6.当nums加入7时,最长子序列[2, 5, 7]或[2, 3, 7],长度3。

7.当nums再加入一个元素18时,最长递增子序列是[2,5,7,101]或者[2,3,7,101]或者[2,5,7,18]或者[2,3,7,18],长度是4。

3.1.2 确定边界

对于nums数组的每一个元素而言,当我们还没有开始遍历寻找时,它们的初始最长子序列就是它们本身长度为1。

3.1.3 找规律,确定最优子结构

通过上面分析,我们可以发现一个规律:

nums[i]结尾的自增子序列,只要找到结尾nums[j]比nums[i]小的子序列,加上nums[i] 就可以。显然,可能形成多种新的子序列,我们选最长那个,就是的最长递增子序列。

得到最优子结构:

最长递增子序列(nums[i]) = max(最长递增子序列(nums[j])) + nums[i]; 0<= j < i, nums[j] < nums[i];

3.1.4 写出状态转移方程

我们设立dp数组储存以nums数组的元素结尾的最长子序列的长度,将其初始化为1,由最优子结构得到状态转移方程:

dp[i] = max(dp[j]) + 1; 0<= j < i, nums[j] < nums[i];

3.1.5 代码
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> dp(nums.size(), 1);
        int ans = 1;
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            ans = max(ans, dp[i]);
        }
        return ans;
    }
};

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

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

相关文章

ros2工作空间

我们先不管ros2工作空间是什么样子的&#xff0c;如果是我自己来搞一个工作空间&#xff0c;我一定是这样安排 一个文件夹用来放自己存放的文件&#xff0c;。。。。。。。。。。对应src文件夹 一个文件夹用来放编译后的文件&#xff0c;。。。。。。。。。。。对应intall文件…

天猫超市电商营销系统:无代码开发实现API连接集成

无代码开发实现天猫超市与电商系统的高效连接 天猫超市&#xff0c;作为天猫推出的网络零售超市&#xff0c;为广大网购消费者提供了一站式的购物服务。而通过无代码开发的方式&#xff0c;天猫超市能够实现与各种电商系统的连接和集成&#xff0c;这种方式无需进行繁琐的API开…

求二叉树中第i层和第i+1层叶子节点个数之和(可执行)

运行环境.cpp 注意&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;如果没有输出结果&#xff0c;一定是输入的建树序列有错误&#xff0c;我建好了2棵树&#xff0c;如果没有输出结果&#xff0c;大家可以用这两棵树试。 main函数的btDepth(t,2)第二个参数是树…

教你如何开设抖音小店, 打造互动社交的线上销售平台

抖音小店是指在中国流行的社交媒体平台抖音上开设的个人或商户经营的电商店铺。通过抖音小店&#xff0c;用户可以方便地浏览和购买各种商品&#xff0c;并与卖家进行交流。以下是四川不若与众关于抖音小店的具体内容和开设流程的介绍。 抖音小店的内容&#xff1a; 1. 商品展…

NX二次开发UF_CAM_is_session_initialized 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;里海NX二次开发3000例专栏 UF_CAM_is_session_initialized Defined in: uf_cam.h int UF_CAM_is_session_initialized(logical * answer ) overview 概述 This function answers whether or not there exists a currently in…

『亚马逊云科技产品测评』活动征文|开发一个手机官网

『亚马逊云科技产品测评』活动征文&#xff5c;开发一个手机官网 授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 前言 …

GitLab的个人仓库转移到团队仓库

文章目录 一、Gitlab权限二、转移2.1、编辑个人仓库2.2、Transfer project2.3、切换Namespace2.4、确认修改 一、Gitlab权限 Gitlab用户在组中有五种权限&#xff1a;Guest、Reporter、Developer、Master、Owner Guest&#xff1a;可以创建issue、发表评论&#xff0c;不能读写…

简单工程模式

代码实现 //simpleFactory.h #ifndef _SimpleFactory_H_ #define _SimpleFactory_H_#include <iostream> #include <exception> #include <string>using namespace std;class Operation { protected:double _numberA 0;double _numberB 0; public:Operat…

VB6批量修改IC卡全部扇区密钥源码

本示例使用设备&#xff1a; Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) 函数声明 Private Declare Function piccreadex Lib "OUR_MIFARE.dll" (ByVal ctrlword As Byte, ByVal serial As Long, ByVal area As Byte, ByVa…

DataFunSummit:2023年数据基础架构峰会-核心PPT资料下载

一、峰会简介 正如From、Join、排序等是SQL的基本算子&#xff0c;存储与计算是也是数据架构中数据生产与消费的基本算子&#xff0c;对于数据架构之下的技术栈层级&#xff0c;我们可将其定义为数据基础架构。 数据存储技术在适应大数据时代的规模需求基础之上&#xff0c;持…

html页面直接使用elementui Plus时间线 + vue3

直接上效果图 案例源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"../js/vue3.3.8/vue.global.js"></script><link rel"styles…

FTX的前世今生:崛起、辉煌与崩塌

FTX&#xff0c;一度被誉为加密货币领域的明星交易所&#xff0c;其快速的崛起和令人瞩目的崩塌吸引了全球的关注。让我们回顾一下FTX的前世今生&#xff0c;了解其短暂的辉煌和骤然的崩塌。 1. 崛起&#xff1a; FTX的创始人山姆班克曼-弗里德在加密货币领域具有深厚的背景和…

人工智能基础_机器学习044_使用逻辑回归模型计算逻辑回归概率_以及_逻辑回归代码实现与手动计算概率对比---人工智能工作笔记0084

上面我们已经把逻辑回归的公式,以及,公式对应的图形都画画出来了,然后我们再来看看 如何用代码实现 可以看到上面是代码,咱们自己去写一下 import numpy as np from sklearn.linear_model import LogistieRegression from sklearn import datasets # 训练数据和测试数据拆分…

编译器安全

在供应链安全中&#xff0c;大家一直关注采用SCA工具分析开源组件中的安全漏洞以及许可证的合规性。但是对于底层软件开发使用的编译器、链接器等安全却容易被忽视&#xff0c;其中有没有安全漏洞、有没有运行时缺陷、有没有被植入漏洞、木马等&#xff0c;似乎并没有引起多少人…

nodejs+vue线上生活超市购物商城系统w2c42

超市管理系统的开发流程包括对超市管理系统的需求分析&#xff0c;软件的设计建模以及编写程序实现系统所需功能这三个阶段。对超市管理系统的需求分析。在这个阶段&#xff0c;通过查阅书籍&#xff0c;走访商场搜集相关资料&#xff0c;了解经营者对软件功能的具体所需和建议…

【计算机毕业设计】Node.js商城APP-97200,免费送源码,【开题选题+程序定制+论文书写+答辩ppt书写-原创定制程序】

Node.js商城APP的开发 摘 要 在传统的商业模式中&#xff0c;对于日常各类商品&#xff0c;人们习惯于到各种商家店铺购买。然而在快节奏的新时代中&#xff0c;人们不一定能为购买各类商品腾出时间&#xff0c;更不会耐心挑选自己想要的商品。所以设计一个商城APP&#xff0c…

【Java源码】智慧工地云平台:工地管理专家

智慧工地是目前建筑行业的热门话题之一&#xff0c;它代表了未来建筑施工的发展趋势。那么&#xff0c;智慧工地的未来&#xff0c;你看好吗&#xff1f; 从技术角度来看&#xff0c;智慧工地无疑是未来发展的趋势。随着人工智能、大数据、云计算等技术的飞速发展&#xff0c;智…

RESTful API 设计指南——开篇词

引言 十年后的今天&#xff0c;我终于学会了RESTful API。 以上&#xff0c;就是我最近一个月的心路历程。入职新公司不到2周&#xff0c;自己都还没完全理解RESTful API就要求给校招应届生培训&#xff0c;着实压力山大。培训结束后也感觉收获颇丰&#xff0c;遂总结分享出来&…

cpupower命令

Linux 内部共有五种对频率的管理策略 userspace &#xff0c; conservative &#xff0c; ondemand &#xff0c; powersave&#xff08;省电模式&#xff09; 和 performance&#xff08;性能模式&#xff09;。 performance: 顾名思义只注重效率&#xff0c;将CPU频率固定…

【AI实用技巧】GPT写sql统计语句

编写sql的统计语句是一项复杂的任务&#xff0c;特别是涉及多表的情况下。但有了GPT的帮助&#xff0c;一切变得轻松愉快。 AI7号 - 最强人工智能&#xff08;GPT&#xff09;中文版https://ai7.pro/s/9v2um 举例说明 有表结构如下&#xff1a; users(user_id, name) bills(…