零钱兑换1【DP】

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

动态规划三要素:

​ 1.重叠子问题

​ 2.最优子结构

​ 3.状态转移方程

​ 3.1明确 base case

​ 3.2明确 状态

​ 3.3明确 选择

​ 3.4定义 dp数组

这题的最优子结构:

​ amount=11的最少数问题与amount=10的最少数问题是相互独立的。

状态转移:

​ 1).base case : amount=0 , 最少数=0

​ 2).状态 : 金钱数量无限,给定amount,那么amount会不断向base case 靠近,所以说唯一的状态就是amount

​ 3).选择 : 就是导致状态改变的行为,导致amount改变就是选择面值来凑amount

​ 4).dp : dp[n] 返回 amount=n的最少金钱数量

方程:

\[dp(n) = \left\{\begin{matrix} 0,&n=0 \\ min(dp(n),1+dp(n-x)&n>0 \end{matrix}\right.\]

class Solution {
public:

    int coinChange(vector<int>& coins, int amount) {

        int dp[10000000];
        for(int i=0;i<10000000;i++)
            dp[i] = 10000000;
        
        if(amount < 0)
            return -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] = min(dp[i],dp[i- coins[j]]+1);
            }
        }
        
        if(dp[amount] >= 10000000)
            return -1;
        else
            return dp[amount];
/*
        long long  sum = 1;
        for(int i=0;i<31;i++)
            sum = sum*2;
        return sum;*/
    }
    
};
posted @ 2020-10-03 13:55  从前有座山,山上  阅读(160)  评论(0编辑  收藏  举报