DP动态规划零钱兑换,原题地址 https://leetcode.cn/problems/coin-change-ii/description/

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。 

这里我举例就是1分 2分 5分 的硬币三种  ,组成1角(就是10分)   ,问有多少种组法

步骤 1:从小金额开始思考

当凑0分   什么都不放  dp[0]=1;  如果不选任何硬币,金额就是 0 分。这是一种“合法”的方式(相当于什么都不做)。因此,dp[0] = 1 表示“用 0 个硬币凑 0 分”有1种方式。

当凑1分   

  • 只能用 1 个 1分硬币。

  • 方法:[1]

  • 所以 dp[1] = 1

当凑2分

  • 方法 1:[1,1](两个 1分)

  • 方法 2:[2](一个 2分)

  • 所以 dp[2] = 2

当凑3分

  • 方法 1:[1,1,1]

  • 方法 2:[1,2]

  • 所以 dp[3] = 2

步骤2 :发现规律

每次用一个新的硬币面额时,可以 “用这个新硬币” 或者 “不用这个新硬币”

  • 如果用新硬币:剩下的金额就是 当前金额 - 新硬币面额,方法数等于 dp[剩余金额]

  • 如果不用新硬币:方法数保持原来的 dp[当前金额]

步骤3:递推公式

dp[当前金额] += dp[当前金额 - 新硬币面额]

代码如下:

int main()
{

    vector<int> Coins{ 1,2,5 };
    int amount = 10;
    vector<int>dp(amount + 1, 0);//初始化为0
    dp[0] = 1;

    for (int coin : Coins)
    {
        for (int i = coin; i <= amount; i++)
        {
            dp[i] = dp[i] + dp[i - coin];

// 等号右边的dp[i]是它表示 在未考虑当前硬币 coin 时,凑出金额 i 的已有方法数

第一次外循环coin为1,只有一种方法,等号右边的dp[i]都为0,第二次外循环,等号右边的dp[i] 为未使用当前coin的方法数 ,此刻的dp[i]为上次循环已经求出的值。
        }
    }
    cout << dp[amount] << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LMX-2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值