数据结构学习 Leetcode322 零钱兑换

关键词:动态规划 完全背包 记忆化搜索

一个套路:

  • 01背包:空间优化之后dp【target+1】,遍历的时候要逆序遍历
  • 完全背包:空间优化之后dp【target+1】,遍历的时候要正序遍历

题目:

方法一:

动态规划 完全背包

思路:

就是一个完全背包问题。有无限个相同的硬币。目标就是amount。

状态:dp[j]判断在放第i种硬币时,凑成目标金额为j所需要的最少硬币个数。(进行了滚动数组进行空间优化,正序遍历)

转移方程: dp[j]=min(dp[j],dp[j-coins[i]]+1)

  • 如果选dp[j]:不加这个硬币。
  • 如果选dp[j-coins[i]]+1:加这一个硬币。

初始条件:因为是找最小值,所以dp初始值设置成一个比较大的值,我设了1e5。

边界条件:初始条件里面,dp[0]要特别设置出来,dp[0]=0。因为在目标为0元、什么硬币都不用的时候,所需要的最少硬币个数为0。

画了一个dp状态推理过程的表格。纵坐标是j,横坐标是i。实际上dp状态是一维的,长度为amount+1,coins维被空间优化了。

amount\coins0125
00
1100001
21000021
31000032
41000042
510000531
610000632
710000742
810000843
910000953
10100001052
11100001163

 复杂度计算:

  • 时间复杂度O(nm) n为amount m为coins.size()
  • 空间复杂度O(n) n为amount

代码:

#include <vector>
#include <iostream>
class Solution {
public:
    int coinChange(std::vector<int>& coins, int amount) {
        if (amount == 0) return 0;
        std::vector<int> dp(amount + 1,1e5);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); ++i)
        {
            for (int j = coins[i]; j <= amount; ++j)
            {
                dp[j] = std::min(dp[j], dp[j - coins[i]] + 1);
            }
        }
        if (dp[amount] == 1e5) return -1;
        else return dp[amount];
    }
};

方法二:

动态规划 记忆化

思路:

记忆化:把之前算过的状态记下来,减少搜索。

 复杂度计算:

  • 时间复杂度O(nm) n为amount m为coins.size()
  • 空间复杂度O(n) n为amount

 代码:

class Solution {
    std::vector<int>count;
    int dp(std::vector<int>& coins, int rem)
    {
        if (rem < 0)return-1;
        if (rem == 0)return 0;
        if (count[rem - 1] != 0)return count[rem - 1];
        int min = INT_MAX;
        for (const auto& coin : coins)
        {
            int res = dp(coins, rem - coin);
            if (res >= 0 && res < min)
            {
                min = res + 1;//为什么要加个1
            }
        }
        count[rem - 1] = min == INT_MAX ? -1 : min;
        return count[rem - 1];
    }
public:
    int coinChange(std::vector<int>& coins, int amount) {
        if (amount < 1) return 0;
        count.resize(amount);
        return dp(coins, amount);
    }
};

题目二:

给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

思路:

和上面唯一不同的是求的是凑成总金额的硬币组合数

其实是基本一样的思路,主要是改变转移方程。

状态:dp[j]判断在放第i种硬币时,凑成目标金额为j的硬币组合数。(进行了滚动数组进行空间优化,正序遍历)

转移方程: dp[j]=dp[j]+dp[j-coins[i]]

  • dp[j]:不加这个硬币,凑成j的组合数。
  • dp[j-coins[i]]:加这一个硬币,凑成j的组合数。

初始条件:因为是找总和,所以dp初始值设置成0。

边界条件:初始条件里面,dp[0]要特别设置出来,dp[0]=1。因为在凑0元的时候,有一个方法就是啥都不放。

画了一个dp状态推理过程的表格。纵坐标是j,横坐标是i。实际上dp状态是一维的,长度为amount+1,coins维被空间优化了。

amount\coins0125
01
101
2012
3012
4013
50134
60145
70146
80157
90158
1001610
1101611

 复杂度计算:

  • 时间复杂度O(nm) n为amount m为coins.size()
  • 空间复杂度O(n) n为amount

代码:

#include <vector>
#include <iostream>
//和前面问题不一样:
//给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
class Solution {
public:
    int coinChange(std::vector<int>& coins, int amount) {
        if (amount == 0) return 0;
        std::vector<int> dp(amount + 1, 0);
        dp[0] = 1;
        for (int i = 0; i < coins.size(); ++i)
        {
            for (int j = coins[i]; j <= amount; ++j)
            {
                dp[j] += dp[j - coins[i]];
            }
        }
       return dp[amount];
    }
};

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

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

相关文章

CodeWhisperer——轻松使用一个超级强大的工具

CodeWhisperer 简介 CodeWhisperer是亚⻢逊云科技出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 CodeWhisperer有以下几个主要用途&#xff1a; 解决编程问题&#xff0c;提供代码建议&#xff0c;学习编程知识等等&#xff0c;并且CodeWhisper…

LLM(八)| Gemini语言能力深度观察

论文地址&#xff1a;https://simg.baai.ac.cn/paperfile/fc2138ce-cadb-4a36-b9f7-c4000dea3369.pdf 谷歌最近发布的Gemini系列模型是第一个在各种任务与OpenAI GPT系列相媲美的模型。在本文中&#xff0c;作者对Gemini的语言能力做了深入的探索&#xff0c;做出了两方面的贡献…

微信小程序开发系列-06事件

什么是事件 事件是视图层到逻辑层的通讯方式。事件可以将用户的行为反馈到逻辑层进行处理。事件可以绑定在组件上&#xff0c;当达到触发条件时&#xff0c;就会执行逻辑层中对应的事件处理函数。事件对象可以携带额外信息&#xff0c;如 id, dataset, touches。 事件分类 事…

C实现数组奇数在前偶数在后排序

一、运行结果&#xff1b; 二、源码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现调整函数move_odd_even函数&#xff1b; void move_odd_even(int arr[], int sz) {//初始化变量值&#xff1b;int left 0;int right sz - 1;//循环判断和…

Arduino开发实例-ADS1232高精度24位ADC数据采样

ADS1232高精度24位ADC数据采样 文章目录 ADS1232高精度24位ADC数据采样1、ADS1232介绍2、硬件准备及接线3、驱动实现1、ADS1232介绍 几乎所有的微控制器都带有 ADC 引脚,但它们缺乏高精度。 在很多项目中,需要对模拟量进行高精度的测量,或者被测信号的电压电平不在单片机的…

2022年全国职业院校技能大赛高职组云计算正式赛卷第三场-公有云

2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 目录 2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 【任务 1】公有云服务搭建[10 分] 【任务 2】公有云服务运维[10 分] 【任务 3】公有云运维…

【我与Java的成长记】之this引用和构造方法的使用详解

系列文章目录 能看懂文字就能明白系列 C语言笔记传送门 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言一、this的使用this引用的特…

机器学习之人工神经网络(Artificial Neural Networks,ANN)

人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…

动态规划08--一和零

题目描述 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的大小&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 思路分析 做到这道题的时候没什么思路&a…

LSTM Siamese neural network

本文中的代码在Github仓库或Gitee仓库中可找到。 Hi, 你好。我是茶桁。 大家是否还记得&#xff0c;在「核心基础」课程中&#xff0c;我们讲过CNN以及LSTM。 卷积神经网络&#xff08;CNN&#xff09;已经在计算机视觉处理中得到广泛应用&#xff0c;不过&#xff0c;2017年…

数字化工业中的低功耗蓝牙模块:实现智能制造的关键

在数字化工业的时代&#xff0c;智能制造成为推动产业升级的关键因素之一。低功耗蓝牙模块作为数字化工业的技术支持&#xff0c;为设备之间的高效通信和数据交换提供了理想的解决方案。本文将深入探讨低功耗蓝牙模块在数字化工业中的关键作用&#xff0c;以及其如何实现智能制…

德鲁伊(Druid)链接PGsql前端请求或者后端自动任务频繁出现IOException

尝试在druid配置文件中增加&#xff1a; socket-timeout: 60000 druid一些版本默认会给链接数据库socket默认10s&#xff0c;超出10s之后socket断开&#xff0c;对于GP数据库报的个IO异常。 &#xff08;对于同样的场景mysql超出10s后提示的是socketTimeOut&#xff0c;所以相…

别再写一堆的 for 循环了!Java 8 中的 Stream 轻松遍历树形结构,是真的牛逼!

可能平常会遇到一些需求&#xff0c;比如构建菜单&#xff0c;构建树形结构&#xff0c;数据库一般就使用父id来表示&#xff0c;为了降低数据库的查询压力&#xff0c;我们可以使用Java8中的Stream流一次性把数据查出来&#xff0c;然后通过流式处理。 我们一起来看看&#x…

三维可视化智慧工地源码,数字孪生可视化大屏,微服务架构+Java+Spring Cloud +UniApp +MySql

源码技术说明 微服务架构JavaSpring Cloud UniApp MySql&#xff1b;支持多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三维可视化管理&#xff0c;与一线生产过程相融合&#…

模糊-神经网络控制 原理与工程应用(绪论)

模糊—神经网络控制原理与工程应用 绪论 模糊和确定系统 在客观世界中&#xff0c;系统可分为确定性系统和模糊性系统&#xff0c;前者可用精确数学模型加以描述&#xff0c;而后者则不能。 输入输出类型 &#xff08;&#xff42;&#xff09;的模糊性输出可通过反模糊化转换…

每周一算法:区间覆盖

问题描述 给定 N N N个闭区间 [ a i , b i ] [a_i,b_i] [ai​,bi​]&#xff0c;以及一个线段区间 [ s , t ] [s,t] [s,t]&#xff0c;请你选择尽量少的区间&#xff0c;将指定线段区间完全覆盖。 输出最少区间数&#xff0c;如果无法完全覆盖则输出 − 1 -1 −1。 输入格式…

【Linux】Linux服务器ssh密钥登录

ssh密码登录 ssh root地址 #需要输入密码ssh密钥登录 Linux之间密钥登录 生成公私钥 #生成公钥私钥 ssh-keygen #默认目录&#xff0c;默认密码空ssh-copy-id #拷贝ID到目标服务器 ssh-copy-id -i id_rsa.pub root192.168.8.22 ssh-copy-id -i id_rsa.pub root192.168.8.33…

安卓无法下载gradle或者下载gradle只有几十k的时候怎么办

简单说明&#xff1a;检查项目根目录的build.gradle文件&#xff0c;新版本的检查setting.gradle文件&#xff0c;看看repositories中有没有mavenCentral()&#xff0c;没有的话&#xff0c;加上&#xff0c;放在前面&#xff0c;把阿里的镜像也放上maven { url ‘https://mave…

linux ARM64 异常

linux 的系统调用是通过指令陷入不同异常级别实现的。arm64 架构的 cpu 的异常级别结构如下&#xff1a; 在上图中&#xff0c;用户层运行在 EL0 也就是异常级别 0&#xff0c;Linux 内核运行在 EL1 也就是异常级别 1&#xff0c;安全可信操 作系统运行在异常级别 2&#xff1a…

k8s的二进制部署和网络类型

k8s的二进制部署 master01&#xff1a;192.168.233.10 kube-apiserver kube-controller-manager kube-scheduler etcd master02&#xff1a;192.168.233.20 kube-apiserver kube-controller-manager kube-scheduler node01&#xff1a;192.168.233.30 kubelet kube-proxy etc…