leetcode 518. Coin Change 2/硬币找零 2

归纳于http://www.cnblogs.com/grandyang/p/7669088.html

原题https://leetcode.com/problems/coin-change-2/description/

518. Coin Change 2(Medium)

You are given coins of different denominations and a total amount of money. Write a function to compute the number of

combinations that make up that amount. You may assume that you have infinite number of each kind of coin.

Note: You can assume that

0 <= amount <= 5000

1 <= coin <= 5000

the number of coins is less than 500

the answer is guaranteed to fit into signed 32-bit integer

Example 1:

Input: amount = 5, coins = [1, 2, 5]

Output: 4

Explanation: there are four ways to make up the amount:

5=5

5=2+2+1

5=2+1+1+1

5=1+1+1+1+1

Example 2:

Input: amount = 3, coins = [2]

Output: 0

Explanation: the amount of 3 cannot be made up just with coins of 2.

Example 3:

Input: amount = 10, coins = [10]

Output: 1

问题描述

  给一个总钱数amount,给一个硬币种类数组,每种硬币的数量你可以想象成足够大,问:允许使用同种硬币,一个有多少种硬币组合方式刚好能凑成总钱数amount?

分析

  比如我们有两个硬币[1,2],钱数为5,那么钱数的5的组成方法是可以看作两部分组成,一种是由硬币1单独组成,那么仅有一种情况(1+1+1+1+1);另一种是由1和2共同组成,说明我们的组成方法中至少需要由一个2,所以此时我们先取出一个硬币2,那么我们只要拼出钱数为3即可,这个3还是可以用硬币1和2来拼,所以就相当于求由硬币[1,2]组成的钱数为3的总组合方法数。

动态规划:dp[i][j]表示用前i个硬币组成钱数为j的不同组合方法

递归式:dp[i][j] = dp[i - 1][j] + (j >= coins[i - 1] ? dp[i][j - coins[i - 1]] : 0);

代码

class Solution {
public:
    int change(int amount, vector<int>& coins)
    {
        if(amount==0)
            return 1;
        if(coins.empty())
            return 0;
        vector<vector<int>> dp(coins.size()+1,vector<int>(amount+1,0));
        dp[0][0]=1;
        //dp[0][j!=0]已被初始化为0了
        for(int i=1;i<=coins.size();++i)
        {
            dp[i][0]=1;
            for(int j=1;j<=amount;++j)
            {
                if(j>=coins[i-1])
                    dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]];
                else
                    dp[i][j]=dp[i-1][j];
/*调试用
            printf("dp[%d][%d] = dp[%d-1][%d] + (%d >= coins[%d-1] ? dp[%d][%d - coins[%d-1]] : 0)", i, j, i, j, j, i, i, j, i);
            printf("= dp[%d][%d] + (%d >= %d ? dp[%d][%d - %d] : 0)", i-1, j,j,coins[i-1],i,j, coins[i - 1]);
            dp[i][j] = dp[i - 1][j] + (j >= coins[i - 1] ? dp[i][j - coins[i - 1]] : 0);
            printf("= %d\n\n", dp[i][j]);
*/
            }
        }
        return dp[coins.size()][amount];
    }
};

原文地址:https://www.cnblogs.com/Joezzz/p/9744370.html

时间: 2024-10-15 08:11:24

leetcode 518. Coin Change 2/硬币找零 2的相关文章

LeetCode 518. Coin Change 2

一看就是用dp来做,但是这道题还是有点意思的. dp[i] = sum_{coin} dp[i-coin] 上述的递推公式看似很对,但是会把重复的情况都考虑进去.举个例子,算dp[5]的时候,dp[5]=dp[0]+dp[4]+dp[3],但是之前算的dp[4]就是从dp[3]计算得到的. 解决办法是,一个一个硬币更新dp,即 dp[i] += dp[i-coin] for each coin.这样,对于当前的coin,dp[i-coin] 一定是不会包含当前coin的. class Solut

硬币找零问题之动态规划

今天我们看一下动态规划的硬币找零问题,主要通过一系列编程题分析动态规划的规律,只要掌握这一规律,许多动态规划的相关问题都可以类比得到. 题目1:给定数组arr,arr中所有的值都是正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数. 举例: arr[5,2,3],aim=20.  4张5元可以组成20元,其他的找钱方案都要使用更多张的货币,所以返回4. 题解: 一眼看去这道题好像可以用贪心算法可解,但是仔细分析发现有

硬币找零&&爬楼梯&&猴子摘香蕉

硬币找零&&爬楼梯&&猴子摘香蕉 假设有几种硬币,如1.3.5,并且数量无限.请找出能够组成某个数目的找零所使用最少的硬币数. #include"CoinProblem.h" #include<iostream> int countNum=MAX; void CoinProblem(int *coin,int Length,int Value,int count){ if(Value==0){ if(countNum>count){ c

DP:硬币找零

在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资.我们应该注意到,人民币的硬币系统是100,50,20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01元,采用这些硬币我们可以对任何一个工资数用贪心算法求出其最少硬币数. 但不幸的是:我们可能没有这样一种好的硬币系统,因此用贪心算法不能求出最少的硬币数,甚至有些金钱总数还不能用这些硬币找零.例如,如果硬币系统是40,30

硬币找零问题

硬币找零问题一个经典问题,也是阐述动态规划法几乎必讲的一个例子. 硬币找零问题描述:现存在一堆面值为 V1.V2.V3 - 个单位的硬币, 各单位的硬币数目不限, 问最少需要多少个硬币才能找出总值为 T 个单位的零钱? 比如: 假设这一堆面值分别为 1.2.5.21.25 元,需要找出总值 T 为 63 元的零钱. 基于动态规划的思想,我们可以从目标值为 1 元开始计算出最少需要几个硬币,然后再求 2 元.3元- 每一次求得的结果都保存在一个数组中,以后需要用到时则直接取出即可. #includ

硬币找零问题的动态规划实现

一,问题描述 给定一组硬币数,找出一组最少的硬币数,来找换零钱N. 比如,可用来找零的硬币为: 1.3.4   待找的钱数为 6.用两个面值为3的硬币找零,最少硬币数为2.而不是 4,1,1 因此,总结下该问题的特征:①硬币可重复多次使用.②在某些情况下,该问题可用贪心算法求解.具体可参考:某种 找换硬币问题的贪心算法的正确性证明 二,动态规划分析 为了更好的分析,先对该问题进行具体的定义:将用来找零的硬币的面值存储在一个数组中.如下: coinsValues[i] 表示第 i 枚硬币的面值.比

nyoj995硬币找零(dp完全背包)

硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该注意到,人民币的硬币系统是 100,50,20,10,5,2,1,0.5,0.2,0.1,0.05, 0.02,0.01 元,采用这些硬币我们可以对任何一个工资数用贪心算法求出其最少硬币数. 但不幸的是: 我们可能没有这样一种好的硬币系统, 因此

NYOJ 995 硬币找零

硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该注意到,人民币的硬币系统是 100,50,20,10,5,2,1,0.5,0.2,0.1,0.05, 0.02,0.01 元,采用这些硬币我们可以对任何一个工资数用贪心算法求出其最少硬币数. 但不幸的是: 我们可能没有这样一种好的硬币系统, 因此

动态规划求解最多有几种方案求解硬币找零问题

一,问题描述 假设有 m 种面值不同的硬币,存储在 coinsValues数组中,现需要使用这些硬币来找钱,各种硬币的使用个数不限. 求对于给定的钱数N,我们最多有几种不同的找钱方式.硬币的顺序并不重要. 二,动态规划分析 为了更好的分析,先对该问题进行具体的定义:将用来找零的硬币的面值存储在一个数组中.如下: coinsValues[i] 表示第 i 枚硬币的面值.比如, 第 i 枚硬币     面值 1                1 2                3 3