零钱兑换


钞票面值coins = [1, 2 , 5, 7, 10],金额:14

dp[i],代表金额i的最优解(最少使用张数),数组dp[]中存储金额1到14的最优解


计算dp[i]时,dp[0],...dp[i-1]都是已知的,而金额i 可由:金额i-1和 1 组合,i-2和2组合,i-5和5组合,i-7和7组合,i-10和10组合。即状态i可由状态i-1,i-2, i- 5,i-7,i-10,5个状态所转移到,故dp[i] = min(dp[i-1],dp[i-2],dp[i-5],dp[i-7],dp[i-10]) + 1。

coins = [1,2,5,7,10],设i代表金额,coins[j]代表第j个面值的金额:

当i - coins[j] >=0且dp[i - coins[j] ]!=-1时,j = 0,1,2,3,4;coins[j] = 1,2,5,7,10

dp[i]  = getmin( dp[i-coins[j] ]) +1

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp;
        //初始化,-1表示这个金额的最优解没有
        for(int i = 0;i<=amount;++i)
            dp.push_back(-1);
        
        dp[0] = 0;
        
        for(int i = 1;i<=amount;++i)//递推金额,从1元到amount元
        {
            for(int j = 0;j < coins.size();++j)//循环面值数组
            {//如果现在这个金额大于等于现在的面值的话,并且,差值是一个最优解可达的金额,那么接下来就要更新当前金额钞票张数了
                if(i-coins[j] >=0  && dp[i-coins[j]]!=-1)
                {//如果这个金额是第一次循环到,等于-1,或者已经有了钞票张数,但是这个张数更大,那么就用更小的张数代替
                    if(dp[i]==-1  ||  dp[i] > dp[i-coins[j]]+1)
                        dp[i] = dp[i-coins[j]] + 1;
                }
            }
        }
        
        return dp[amount];
    }
};


猜你喜欢

转载自blog.csdn.net/qq_22080999/article/details/80860182
今日推荐