一文彻底弄懂动态规划【DP】

在这里插入图片描述

动态规划是一种重要的算法,它能解决很多看似复杂的问题,关键在于找到问题的子问题结构,并根据子问题的解决方式来解决原问题。首先要了解的是动态规划的基本思想:

动态规划的基本思想是:将一个复杂的问题分解为一系列相关的子问题,每个子问题只解决一次,并将结果储存在一个可以查找的数据结构中(通常是一个数组或表格)。当要解决相同的子问题时,不需要重新计算,而是可以直接从表格中获取已经计算过的结果。这种使用了额外的存储空间来节省计算时间的方法,常被称为空间换时间。动态规划关键在于如何定义子问题和状态,如何寻找和计算状态转移。

动态规划主要包含三个步骤:

  • 定义状态:状态可以看做是原问题的子问题,通常是对应的一个或多个变量。例如,在背包问题中,状态就是当前放入背包的物品的总价值。

  • 状态转移方程:状态转移方程描述了状态之间的关系。例如,在背包问题中,当前的总价值可以由之前的物品价值和当前物品的价值得出。

  • 初始化和边界条件:动态规划解决问题时,需要一个初始状态作为问题的起点,并在问题解决的过程中处理好边界条件。

下面介绍五个经典的动态规划问题,以及它们的解决思路和代码表示:

  1. 斐波那契数列

这是最简单的动态规划问题,它描述的是一种特殊的数列:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2) (n>=2),要求出第n项的数值。

解题思路:假设dp[i]表示第i个斐波那契数,状态转移方程为dp[i] = dp[i-1] + dp[i-2]

vector<int> fib(int N) {
    vector<int> dp(N+1, 0);
    dp[0] = 0; // 初始化
    dp[1] = 1; // 初始化
    for(int i = 2; i <= N; i++){
        dp[i] = dp[i-1] + dp[i-2]; // 状态转移方程
    }
    return dp[N];
}
  1. 凑零钱问题

这是一种找零问题,给定不同面额的硬币和一个总金额,每种硬币的数量无限,求出能拼凑出总金额所需的最少的硬币个数。

解题思路:假设dp[i]表示拼出金额i所需的最少硬币个数,状态转移方程为dp[i] = min(dp[i], dp[i-coin]+1)其中coin为所有硬币面额。

int coinChange(vector<int>& coins, int amount) {
    vector<int> dp(amount + 1, amount + 1);
    dp[0] = 0;
    for (int i = 1; i <= amount; i++) {
        for (int coin : coins) {
            if (coin <= i) {
                dp[i] = min(dp[i], dp[i - coin] + 1);
            }
        }
    }
    return dp[amount] > amount ? -1 : dp[amount];
}
  1. 最长公共子序列

给出两个字符串,求出他们的最长公共子序列的长度。

解题思路:假设dp[i][j]表示字符串1的前i个字符和字符串2的前j个字符的最长公共子序列的长度,当str1[i]==str2[j]时,dp[i][j]等于dp[i-1][j-1]+1,否则等于max(dp[i-1][j], dp[i][j-1])

int longestCommonSubsequence(string text1, string text2) {
    int m = text1.length(), n = text2.length();
    vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
    for(int i = 1; i <= m; i++){
        for(int j = 1; j <= n; j++){
            if(text1[i-1] == text2[j-1]){
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else{
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }
    return dp[m][n];
}
  1. 0-1背包问题

这是一种很经典的动态规划问题,给定一组物品的重量和价值,一个能承受最大重量的背包,求出能装入背包的物品的最大价值。

解题思路:假设dp[i][j]表示前i个物品重量不超过j的最大价值,状态转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])

int knapsack(vector<int>& weight, vector<int>& value, int W) {
    int n = weight.size();
    vector<vector<int>> dp(n+1, vector<int>(W+1, 0));
    
    for(int i = 1; i <= n; i++){
        for(int j = W; j >= 1; j--){
            if(j >= weight[i-1]){
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i-1]] + value[i-1]);
            }
            else{
                dp[i][j] = dp[i-1][j];
            }
        }
    }
    return dp[n][W];
}
  1. 最长递增子序列

给出一个无序的整数数组,求出它的最长递增子序列的长度。

解题思路:假设dp[i]表示以第i个数字结尾的最长上升子序列长度,状态转移方程为dp[i] = max(dp[i], dp[j] + 1)(对所有0<=j<i,如果nums[i]>nums[j])。

int lengthOfLIS(vector<int>& nums) {
    if (nums.empty())
        return 0;
    vector<int> dp(nums.size(), 1);
    int res = 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);
            }
        }
        res = max(res, dp[i]);
    }
    return res;
}

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接: 人工智能交流群【最新顶会与项目实战】(点击跳转)

在这里插入图片描述

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

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

相关文章

Qt将打印信息输出到文件

将打印信息&#xff08;qDebug、qInfo、qWarning、qCritial等&#xff09;输出到指定文件来以实现简单的日志功能。 #include "mainwindow.h" #include <QApplication> #include <QLoggingCategory> #include <QMutex> #include <QDateTime>…

Windows安装MySQL8.2

Windows安装MySQL8.2 三种安装模式 默认自定义完整 本案例选择自定义 选择安装目录 勾选 Run MySQL Configurator 配置MYSQL 默认为开发者模式 在 Config Type 下拉列表中选择数据中心 设置 root 账号密码

【专题】【数列极限】

【整体思路】 【常用不等式】

前后端分离部署https

引用&#xff1a;https://blog.csdn.net/weixin_35676679/article/details/127841598 前后端部署&#xff0c;&#xff0c;一般用的是nginx和java&#xff0c;&#xff0c;&#xff0c; 下载SSL证书&#xff1a; java配置https 将证书配置到springboot中 server:port: 544…

动态规划 | 打家劫舍1、2、3

198. 打家劫舍 https://leetcode.cn/problems/house-robber/description/ dp[i] 表示 考虑到下标为 i &#xff08;包括i&#xff09;的房子&#xff0c;可以偷到的最大金额。 dp[i] 有两个状态&#xff0c;分别是 偷 和 不偷。 偷&#xff0c;则需要考虑前 i-2 天的最大金额…

Google Colab 现已支持直接使用 transformers 库

Google Colab&#xff0c;全称 Colaboratory&#xff0c;是 Google Research 团队开发的一款产品。在 Colab 中&#xff0c;任何人都可以通过浏览器编写和执行任意 Python 代码。它尤其适合机器学习、数据分析和教育目的。从技术上来说&#xff0c;Colab 是一种托管式 Jupyter …

Mysql窗口函数

1 什么是窗口函数 MySQL从8.0开始支持窗口函数&#xff0c;有的也叫分析函数&#xff08;处理相对复杂的报表统计分析场景&#xff09;&#xff0c;这个功能在大多商业数据库和部分开源数据库中早已支持。 窗口函数&#xff1a;窗口、函数&#xff08;应用在窗口内的函数&…

Dockerfile与Docker网络

一、Dockerfile 1、概念&#xff1a; Dockerfile是用来构建docker镜像的文本文件&#xff0c;是由构建镜像所需要的指令和参数构建的脚本。 2、构建步骤&#xff1a; ① 编写Dockerfile文件 ② docker build命令构建镜像 ③ docker run依据镜像运行容器实例 Dockerfile …

深入理解:Class.getResource与ClassLoader.getResource使用区别

深入理解&#xff1a;Class.getResource与ClassLoader.getResource使用区别 一作用&#xff1a;都是使用类的类加载器来读取某个文件&#xff0c;从而获取该文件的URL对象二Class.getResource()方法读取文件&#xff1a;1.若文件路径以“/”开头&#xff0c;则该方法会从classp…

洛谷 P9516 color C++代码

目录 前言 思路点拨 AC代码 结尾 前言 今天我们来做洛谷上的一道题目。 网址&#xff1a;color - 洛谷 题目&#xff1a; 思路点拨 这题就是if-else判断输入的五个数据和不就OK了&#xff1f; 在这里我的估值是183&#xff08;截止2023.12.3&#xff09;&#xff0c;热…

软件工程单选多选补充

2. 4. 5. 6. 7. 8. 9. 10. 12。 13.

Zabbix监控接收SNMPTrap消息与SNMPTT结合

一.SNMP 协议 1.协议介绍 snmp 协议是日常使用的较多的一种协议&#xff0c;绝大多数网络设备/存储等都支持 snmp 协议&#xff0c;通过此协议可以实现设备状态的监控及管理。 2.主要组成 SNMP 协议包括以下三个部分: SNMP Agent&#xff1a;负责处理 snmp 请求&#xff0c…

k8s中批量处理Pod应用的Job和CronJob控制器、处理守护型pod的DaemonSet控制器介绍

目录 一.Job控制器 1.简介 2.Jobs较完整解释 3.示例演示 4.注意&#xff1a;如上例的话&#xff0c;执行“kubectl delete -f myJob.yaml”就可以将job删掉 二.CronJob&#xff08;简写为cj&#xff09; 1.简介 2.CronJob较完整解释 3.案例演示 4.如上例的话&#xf…

应用安全四十三:无密码认证安全

什么是无密码认证&#xff1f; 无密码认证是一种新兴的安全技术和身份认证手段&#xff0c;是用密码以外的东西验证软件用户身份的过程&#xff0c;旨在替代传统的用户账号和密码认证方法&#xff0c;提高账号的安全性和用户体验。无密码技术通过生物识别、多因素认证、基于硬…

长度最小的子数组(Java详解)

目录 题目描述 题解 思路分析 暴力枚举代码 滑动窗口代码 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条…

Prime 1.0

信息收集 存活主机探测 arp-scan -l 或者利用nmap nmap -sT --min-rate 10000 192.168.217.133 -oA ./hosts 可以看到存活主机IP地址为&#xff1a;192.168.217.134 端口探测 nmap -sT -p- 192.168.217.134 -oA ./ports UDP端口探测 详细服务等信息探测 开放端口22&#x…

【Linux】进程控制-进程创建

目录 一、fork()是什么&#xff1f; 二、fork返回值问题 1、fork()的两个返回值是什么&#xff1f; 2、fork()为什么有两个返回值&#xff1f; 3、一个变量为什么会保存两个不同的值&#xff1f; 三、写时拷贝 1、写时拷贝是什么 2、为什么要写时拷贝 3、写时拷贝的示意…

GEE:均值滤波

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上,进行均值滤波操作的代码框架、核心函数和多种卷积核。 并分别以林地区域和农田区域为试验区,以NDVI图像为例。结果如下图所示, 文章目录 一、均值滤波二、完整代码三、代码链接一、均值滤波 均值滤…

Docker常用进本命令【必备基本功】

docker常用命令 1.帮助命令 1.查看当前docker 版本 docker version2.查看docker的详细信息 docker info3.docker的帮助命令 docker --help2.镜像命令 镜像命令说明docker images列出本地主机的镜像docker search 镜像名称从docker HUB上搜索镜像docker pull 镜像名称从…
最新文章