322. Coin Change

来源:互联网 发布:google picasa mac 编辑:程序博客网 时间:2024/06/11 09:22

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)

Example 2:
coins = [2], amount = 3
return -1.

Note:
You may assume that you have an infinite number of each kind of coin.

s思路:
1. 看到这种题,就想到backtracking啊,recursive啊。
2. 但又不完全是,题目和以前的题目还是有差别。
3. 有点繁琐,看了hint,需要用dp。可不是吗?首先求最值,然后用coins的和得到给的一个target,那么组成的过程就是从元问题开始,一步一步的得到这个target的。这样,就更要用dp了
4. 也就是说,下次看到这类题,还应该先想想dp.
5. 这个dp想明白了,也很简单。从元问题开始,加上所有的硬币,得到一个硬币数,然后amount++,整个复杂度就是o(amount*number of coins)
6. 当然也可以在每个位置减去硬币数

//方法1:dpclass Solution {public:    int coinChange(vector<int>& coins, int amount) {        //        if(amount==0) return 0;        sort(coins.begin(),coins.end());        //if(coins[0]>amount) return -1;        vector<int> dp(amount+1,INT_MAX);        dp[0]=0;        for(int i=0;i<amount;i++){            for(int c:coins){                if(i>0&&dp[i]==INT_MAX||i+long(c)>amount) continue;//bug:                dp[i+c]=min(dp[i+c],dp[i]+1);            }        }        return dp[amount]==INT_MAX?-1:dp[amount];    }};//方法1.1:改进了dp,初值不用int_max,而用更严格的界限,即:最大值为amount+1,问题就简单了!class Solution {public:    int coinChange(vector<int>& coins, int amount) {        //        if(amount==0) return 0;        vector<int> dp(amount+1,amount+1);        dp[0]=0;        for(int i=0;i<coins.size();i++){            for(int j=coins[i];j<=amount;j++){//bug:两个for循环交换位置,就不用判断是否前一个值不能有硬币构成,这个确实妙,一般不容易看到!小trick                dp[j]=min(dp[j],dp[j-coins[i]]+1);              }            }        return dp[amount]==amount+1?-1:dp[amount];    }};
0 0