LeetCode -- Coin chane

来源:互联网 发布:ubuntu启动mysql服务 编辑:程序博客网 时间:2024/05/22 16:07
题目描述:


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.


分析: 
给定硬币数组和指定金额,返回能够换得指定金额所使用最少的硬币数。
此题一开始看以为使用贪心,后来想想会遗漏情况,因为硬币可以重复使用。
从回溯的角度来看有点多余,因为并没有要求列举出所有情况数,只是求最值。


对于coins{1,2,5}假设amount为其中之一,只需要一枚硬币。
从DP角度考虑,设dp[i]为金额为i时所需的最小硬币数字。即
dp[coints[i]] = 1 , 其中coints[i] < amount
再逐个更新dp[i], i∈[1,amount] ,得到递推公式:
dp[i] = Min(dp[i], dp[i-coints[j]]+ dp[coins[j]] )
其中j∈[0,coints.Length] , i∈[1,amount] . dp[i-coins[j]] 与dp[coints[j]]均可换 (判断是否可换:可以初始化dp的每个元素为-1,如果仍未-1,说明不可换)。


实现代码:


public class Solution {    public int CoinChange(int[] coins, int amount) {                if(amount == 0){            return 0;        }                var dp = new int[amount+1];    //// change for 0 need 0    dp[0] = 0;    for(var i = 1;i < dp.Length; i++){    dp[i] = -1;    }        //// change for coin amount only need 1     //// say {2,5}    //// dp[2] = 1, dp[5] = 1    for(var i = 0;i < coins.Length; i++){    if(coins[i] < dp.Length){    dp[coins[i]] = 1;    }    }        // say {1,2...11}    for(var i = 1;i <= amount; i++){        // no need to update, already min    if(dp[i] == 1){    continue;    }        // say {2,5}    // update dp array each element    for(var j = 0;j < coins.Length; j++){    // if changable, update        if(i-coins[j] > 0 && dp[i - coins[j]] != -1){if(dp[i] == -1 || dp[i] > dp[coins[j]] + dp[i-coins[j]]){dp[i] = dp[coins[j]] + dp[i-coins[j]];}    }    }    }        return dp[amount];    }}


1 0
原创粉丝点击