Leetcode刷题92-322. 零钱兑换(C++详细解法!!!)

Come from : [https://leetcode-cn.com/problems/coin-change/submissions/]

53. Maximum Subarray

  • 1.Question
  • 2.Answer
  • 3.我的收获

1.Question

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:

Input: coins = [1, 2, 5], amount = 11
Output: 3 
Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3
Output: -1

Note:

Input: coins = [2], amount = 3
Output: -1

2.Answer

easy 类型题目。.
首先来总结一下动态规划的一般解题步骤:

  1. 首先确定 原问题子问题
    本题中,原问题是求前 i 个数字组成的 连续最大字段和
    但是子问题的选择 很重要:一般有两种选法:

a) 设子问题是求前1个数字组成的 连续最大字段和,前2个数字组成的 连续最大字段和。。。前n个数字组成的 连续最大字段和
分析:此设计状态的方法,不能推导出dp[i],因为连续数组内在没有直接的关系。下面我们来换种方式思考。
b)如果设第 i 个状态 (dp[i]) , 代表以 第 i 个数字结尾 的最大连续字段和 ,那么就能推导出接下来的状态。

  1. 确认状态
    第i个状态即为以 第 i 个数字结尾 的最大连续字段和。
  2. 确认边界的状态
    dp[0] = nums[0]。
    dp[1] = max(dp[0] + nums[i], nums[i],)。
  3. 确定状态转移方程
    dp[i] = max(dp[i-1] + num[i], nums[i]); 其中 i >=1

AC代码如下:

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp;
        for(int i = 0; i <= amount; ++i)
        {
            dp.push_back(-1);
        }
        dp[0] = 0;
        for(int i = 1; i <= amount; ++i)
        {
            for(int j = 0; j < coins.size(); ++j)
            {
                if(i-coins[j] >=0 && dp[i-coins[j]] != -1)
                {
                    if(dp[i] == -1 || dp[i] > dp[i-coins[j]] + 1)
                    {
                        dp[i] = dp[i - coins[j]] + 1;
                    }
                }
            }
        }
        return dp[amount];
    }
};

3.我的收获

感觉还是要系统的掌握知识。。。
比如这次的 动态规划 day3。。。
系统的学习之后,才能更加得心应手的运用~

2019/6/3 胡云层 于南京 92

你可能感兴趣的:(LeetCode从零开始)