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

题目:

链接:LeetCode 518. 零钱兑换 II

难度:中等

动态规划:

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

  • dp0j = 0, 1 <= j <= amount(不选取任何硬币的情况下,组成正整数金额的组合数为0)
  • dpi0 = 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)。

相关推荐
CoderYanger7 分钟前
A.每日一题:856. 括号的分数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
wyhwust16 分钟前
No1-绪论
c++
kiracrimson20 分钟前
选择排序与快速排序:一次选极值,一次分区间
算法·排序算法
无名猿21 分钟前
C++ 对象内存模型:vtable 布局、多继承 vptr、RTTI 与 dynamic_cast 走查
c++·内存管理·调试技巧·现代c++
All for pursuit.39 分钟前
【动态规划-8】152.乘积最大子数组
数据结构·c++·算法·leetcode·动态规划
信奥卷王42 分钟前
[GESP202512 六级] 路径覆盖
数据结构·算法
INGNIGHT1 小时前
1861 · 老鼠跳跃(坐标型dp)
数据结构·c++
Lazionr1 小时前
手撕 unordered_set 和 unordered_map,剖析哈希表底层实现
c++·算法
0+1111 小时前
算法 --归并排序
数据结构·算法·排序算法
Run_Teenage1 小时前
算法:树的重心、树的直径
算法