LeetCode 518. 零钱兑换 II(动态规划 完全背包)

题目:

链接:LeetCode 518. 零钱兑换 II

难度:中等

动态规划:

dp[i][j] 定义 :可选前 i 种硬币的情况下,组成金额 j 的组合数。
初始状态

  • dp[0][j] = 0, 1 <= j <= amount(不选取任何硬币的情况下,组成正整数金额的组合数为0)
  • dp[i][0] = 1, 0 <= i <= n(金额为0的情况下,只有空集的这一种组合才是0)

状态转移方程

cpp 复制代码
	if(j - coins[i - 1] >= 0)  // 容量足够选取该硬币:组合数=选取该硬币和不选该硬币两种状态相加
		dp[i][j] = dp[i][j - coins[i - 1]] + dp[i - 1][j];
	else
		dp[i][j] = dp[i - 1][j];  // 容量不足以选取该硬币:组合数=不选该硬币的组合数

代码:

cpp 复制代码
class Solution {
public:
    int change(int amount, vector<int>& coins) {
        int n = coins.size();
        vector<vector<int>> dp(n + 1, vector<int>(amount + 1, 0));  // dp[i][j]:i代表使用前i种硬币,j代表金额
        for(int i = 0; i <= n; i++)  // 初始化,组成金额为0的方案数总是1(不选任何硬币)
            dp[i][0] = 1;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= amount; j++)
            {
                if(j - coins[i - 1] >= 0)  // 容量足够选取该硬币:组合数=选取该硬币和不选该硬币两种状态相加
                    dp[i][j] = dp[i][j - coins[i - 1]] + dp[i - 1][j];
                else
                    dp[i][j] = dp[i - 1][j];  // 容量不足以选取该硬币:组合数=不选该硬币的组合数
            }
        }
        return dp[n][amount];
    }
};

时间复杂度O(N * amount),N是coins数组长度。

空间复杂度O(N * amount)。

相关推荐
鸣弦artha31 分钟前
蓝桥杯——杨辉三角
java·算法·蓝桥杯·eclipse
我是聪明的懒大王懒洋洋34 分钟前
力扣力扣力:动态规划入门(1)
算法·leetcode·动态规划
未知陨落38 分钟前
数据结构——二叉搜索树
开发语言·数据结构·c++·二叉搜索树
丶Darling.39 分钟前
Day44 | 动态规划 :状态机DP 买卖股票的最佳时机IV&&买卖股票的最佳时机III
算法·动态规划
一丝晨光1 小时前
gcc 1.c和g++ 1.c编译阶段有什么区别?如何知道g++编译默认会定义_GNU_SOURCE?
c语言·开发语言·c++·gnu·clang·gcc·g++
TN_stark9322 小时前
多进程/线程并发服务器
服务器·算法·php
汉克老师2 小时前
GESP4级考试语法知识(贪心算法(四))
开发语言·c++·算法·贪心算法·图论·1024程序员节
smj2302_796826523 小时前
用枚举算法解决LeetCode第3348题最小可整除数位乘积II
python·算法·leetcode
CyberMuse3 小时前
表的数据结构和常见操作
数据结构
爱吃生蚝的于勒3 小时前
C语言最简单的扫雷实现(解析加原码)
c语言·开发语言·学习·计算机网络·算法·游戏程序·关卡设计