「动态规划dp」

news2024/11/14 20:47:27

文章目录

  • 0 概览
  • 1 步骤
    • 1.1 框架
  • 2 刷题
    • 2.1 斐波那契数列
      • 2.1.1 题解
      • 2.1.2 Code
      • 2.1.3 结果
    • 2.2 零钱兑换
      • 2.2.1 题解
      • 2.2.2 Code
      • 2.2.3 结果

0 概览

动态规划的题型,一定是要求解最值的,比如最短编辑距离,最长递增子序列,最长公共子序列,求最值得问题,核心一定是穷举,先穷举所有可行解,再找出最优的。状态转移方程是最重要的,最关键的,因为重叠子问题与最优子结构可以理解为动态规划的两个特性,状态转移方程是求解动态规划问题的一个思路,所以说是最关键的,特性的意思就是说,发现这个题有重叠子问题和最优子结构,就知道这是一个dp问题,而解法还得是状态转移方程,状态转移方程就是为了穷举,找出最优解。

1 步骤

  1. 明确状态(会变的, d p dp dp函数参数)
  2. 明确选择(递归找到最优)
  3. 明确 d p dp dp定义(状态方程)
  4. 明确 b c bc bc(比如说,第一行,第一列,全初始化某些值)

1.1 框架

// 初始化 bc
dp[0][0][...] = base;

//状态转移
for 状态1 in 状态1的所有取值:
	for 状态2 in 状态2的所有取值:
		for ...
			dp[状态1][状态2][...] = 求最值(选择1,, 选择2, ...)

在经典dp问题当中,最小编辑距离当中,就是分为以上的几步状态,初始化 b a s e c a s e base case basecase,穷举,进行状态转移。


  • 图片来自东哥
    在这里插入图片描述

2 刷题

2.1 斐波那契数列


在这里插入图片描述


2.1.1 题解

如果是采用递归的方法写的话,会发现算法的计算效率有点低,因为递归的时间复杂度为:递归函数调用的次数 * 递归函数本身的复杂度。并且递归还会造成很多的冗余计算,所以为了防止递归造成冗余计算,就想出了一个备忘录递归,这样可以避免进行冗余计算(把树形的结构转换成了链式的结构,备忘录可以防止重复计算),这是一个自顶向下的dp思想。


  • 图片来自东哥,先自顶向下的去寻找,接着自顶向上的回溯。
    图片来自东哥

最后,因为只需要前两个数的值,就能推到要推的数,所以继续进行优化,得到最终版本。

2.1.2 Code

//递归
class Solution {
public:
    int fib(int n) {
        if (n == 0 || n == 1) return n;
        return fib(n - 1) + fib(n - 2);
    }
};
//备忘录
class Solution {
private:
    vector<int> memo;
public:
    int fib(int n) {
        memo.resize(n + 1);
        return helper(memo, n);
    }

    int helper(vector<int> memo, int n)
    {
        if (n == 0 || n == 1) return n;
        if (memo[n] != 0) return memo[n];
        memo[n] = helper(memo, n - 1) + helper(memo, n - 2);
        return memo[n];
    }
};
//空间复杂度优化
class Solution {
public:
    int fib(int n) {
        //base case
        if (n == 0 || n == 1) return n;

        //递推
        int prev = 0, curr = 1;
        for (int i = 2; i <= n; ++i)
        {
            int sum = prev + curr;
            prev = curr;
            curr = sum;
        }
        return curr;
    }
};

2.1.3 结果


在这里插入图片描述


2.2 零钱兑换


在这里插入图片描述


2.2.1 题解

因为这是要求计算所需的最少硬币的个数,这是一个求最值的问题,所以想到可以使用dp来进行求解,利用框架几步走,一步一步来就行。

2.2.2 Code

class Solution {
    //状态:目标金额amount(函数参数中会变化的量)
    //选择:coins数组中列出的所有硬币面值(导致你状态变化的就是选择)
    //函数的定义:凑出总金额amount,至少需要coinChange(coins, amount)枚硬币
    //base case:amount == 0时,需要0枚硬币;amount < 0时,不可能凑出,return -1
private:
    vector<int> memo;
public:
    int coinChange(vector<int>& coins, int amount) {
        memo.resize(amount + 1);
        memo.insert(memo.begin(), memo.size(), -666);//先让其元素为负值
        //base case
        return dp(coins, amount);
    }
    int dp(vector<int> coins, int amount){
        if (amount == 0) return 0;
        if (amount < 0) return -1;
        //查备忘录,防止重复计算

        if (memo[amount] != -666) return memo[amount];

        int res = INT_MAX;
        for (int coin : coins)
        {
            //计算子问题的结果
            int subProblem = dp(coins, amount - coin);
            //子问题无解则跳过
            if (subProblem == -1) continue;
            //在子问题当中选择最优解,然后+1
            res = min(res, subProblem + 1);
        }
        memo[amount] = (res == INT_MAX) ? -1 : res;
        return memo[amount];
    }
};

2.2.3 结果

在这里插入图片描述

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

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

相关文章

删除每行中的最大值

给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。 将删除元素中的最大值与答案相加。 注意 每执行一次操作&…

Python - OpenCV识别条形码、二维码(已封装,拿来即用)

此代码可识别条形码和二维码&#xff0c;已封装好&#xff0c;拿来即用&#xff1a; import cv2 import pyzbar.pyzbar as pyzbar import numpy from PIL import Image, ImageDraw, ImageFontclass CodeScan():def __init__(self):super(CodeScan, self).__init__()def decode…

uniapp checkbox radio 样式修改

文章目录 通过查看代码&#xff0c;发现 before部分是设置样式的主要属性 我们要设置的话&#xff0c;就要设置checkbox::before的属性。 其中的content表示内容&#xff0c;比如内部的对勾 那么我们设置的时候&#xff0c;比如设置disabletrue的时候或者checkedtrue的时候&…

Redis(三)—— Redis基本的事务操作、Redis实现乐观锁

一、Redis基本的事务操作 首先声明&#xff1a; redis的单条命令是保证原子性的&#xff08;回想一下setnx k1 v1 k5 v5命令如果k1已经存在&#xff0c;那么k5也会设置失败&#xff09;但是redis的事务不保证原子性&#xff01;见下面“1.2 某条命令有错怎么办&#xff1f;”…

产品经理:如何做好项目需求管理

产品经理每天都要接触各种不同的需求&#xff0c;只有对这些需求进行分析&#xff0c;才能更好地了解问题&#xff0c;从而制定相应的解决方案。那么&#xff0c;怎么做需求分析呢&#xff1f; 一、需求确定 选择需求是很重要的&#xff0c;先做出选择&#xff0c;才会有对应的…

Item2连接SSH

在MocOS系统上&#xff0c;没有xshell&#xff0c;而一些类似xshell的工具中&#xff0c;好用的要收费&#xff0c;免费的不好用&#xff0c;于是决定使用iTerm2打造一个好用的ssh神器。 一、新建一个Profile 在配置管理页面切换到Profiles管理页面&#xff1a; 二、配置ssh连接…

五、控制流(1)

本章概要 true 和 falseif-else迭代语句 whiledo-whilefor 逗号操作符 for-in 语法 程序必须在执行过程中控制它的世界并做出选择。 在 Java 中&#xff0c;你需要执行控制语句来做出选择。 Java 使用了 C 的所有执行控制语句&#xff0c;因此对于熟悉 C/C 编程的人来说&…

KNN模型进行分类和回归任务

KNN工作原理 “近朱者赤&#xff0c;近墨者黑”可以说是KNN的工作原理。整个计算过程分为三步&#xff1a;1:计算待分类物体与其他物体之间的距离&#xff1b;2:统计距离最近的K个邻居&#xff1b;3:对于K个最近的邻居&#xff0c;它们属于哪个分类最多&#xff0c;待分类物体就…

【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

Nginx学习&#xff1a;HTTP核心模块&#xff08;九&#xff09;浏览器缓存与try_files 浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置&#xff0c;这一块也是 HTTP 的基础知识。之前我们就一直在强调&#xff0c;学习 Nginx 需要的就是各种网络相关的基础知识&…

前端程序员入门:先学Vue3还是Vue2?

一、前言 对于新手来说&#xff0c;学习Vue.js框架时往往会有这样一个疑问&#xff1a;应该先学习Vue2还是直接学习Vue3&#xff1f;在回答这个问题之前&#xff0c;我们先简单介绍一下Vue.js框架。 Vue.js是一个轻量级的MVVM(Model-View-ViewModel)框架&#xff0c;它以数据驱…

数字世界未来十年面貌展望

2023年&#xff0c;数字技术已经深刻改变了我们的生活和社会&#xff0c;而未来十年数字世界的面貌将会更加令人瞩目。从人工智能到区块链&#xff0c;从虚拟现实到5G&#xff0c;各种科技将继续发展演进&#xff0c;给我们带来更多令人兴奋的可能性。以下是对数字世界未来十年…

交换机之HOL拥塞

队首阻塞(Head of Line Blocking, HOL)是一种出现在缓存式通信网络交换中的一种现象&#xff0c;其交换结构通常由缓存式FIFO输入端、交换结构(Switch Fabric)、FIFO输出端构成。 HOL阻塞用一个现实生活中的例子说明&#xff0c;就如同你在一条单车道的马路上右转&#xff0c;…

人机交互与人机混合智能的区别

人机交互和人机融合智能是两个相关但不完全相同的概念&#xff1a; 人机交互是指人与计算机之间的信息交流和互动过程。它关注的是如何设计和实现用户友好的界面&#xff0c;以便人们能够方便、高效地与计算机进行沟通和操作。人机交互通常强调用户体验和界面设计&#xff0c;旨…

如何找回删除的文件?文件恢复,3招就行!

“昨天不小心把我的毕业资料删除了&#xff0c;因为改了很多版&#xff0c;删除的时候没想到把正确的版本删除了&#xff0c;错误的版本还在&#xff01;这种情况应该怎么办呢&#xff1f;怎样才能找回我删除的文件呀&#xff1f;” 对于一些比较重要的文件&#xff0c;不小心删…

【C++初阶】C++基础(上)——C++关键字、命名空间、C++输入输出、缺省参数、函数重载

目录 1. C关键字 2. 命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C输入&输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C支持函数重载的原理——名字修饰&#xff08;name Mingling&#xff09; 5.3 extern &…

围棋基础知识

1、气 1.1星位位置 1.2天元位置 1.3 气的位置 2、禁入点 白棋里面的位置就是禁入点&#xff0c;也可以称为没有气的位置可以称为禁入点 破解之法&#xff1a; 在于将白棋全部围住&#xff0c;下一步为围住之策&#xff0c;即可。 3、死棋和活棋 3.1活棋 3.2 死棋 白棋的样…

探寻数据服务的本质:API之外的可能性

数据服务在数据建设中发挥着重要的作用。数据服务到底啥样&#xff1f; 是不是只对外提供一个API&#xff1f; 这么简单&#xff1f; 而我希望你能在学完这部分内容之后&#xff0c;真正掌握数据服务的产品功能设计和系统架构设计。因为这会对你设计一个数据服务&#xff0c;或…

青少年护眼灯哪个好?2023全新五款台灯推荐

国内儿童青少年的视力健康问题越来越突出&#xff0c;甚至许多孩子年纪非常小就已经近视了&#xff0c;所以许多老师以及眼科医生都和家长们强调护眼台灯的重要性。不过&#xff0c;护眼台灯虽好&#xff0c;但在选购时也要注意那些无法护眼的不专业品牌&#xff0c;许多产品有…

ICC2如何计算Gate Count?

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f;知识星球入口 我们认为gate count等于standard cell(非physical only)总面积 / 最小驱动二输入与非门面积。 ICC2没有专门的命令去报告gate count&#xff0c;只能自己计算&#xff0c;使用report_d…

MySQL数据库——DDL基本操作

文章目录 前言数据库操作查看已存在的所有数据库创建数据库选中数据库删除数据库修改数据库编码 表操作创建表显示创建表时的语句显示表结构删除表修改表的结构增加列修改列删除列 修改表名 前言 DDL 操作是与数据库结构相关的操作&#xff0c;它们不涉及实际的数据操作&#…