1. 程式人生 > >動態規劃解決最少硬幣湊成m元錢

動態規劃解決最少硬幣湊成m元錢

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.

public class Solution
{
    /*長度為m的陣列c[1...m]中存放一系列子結果,即c[i]為要湊的錢數為i時所需的最少硬幣數,則c[m]為所求
  當要找的錢數i(1<i<m)與當前所試探的硬幣面值k相等時,結果為1,即c[i]=1
  當i大於當前所試探硬幣面值k時,若c[i]為0,即還未賦過值,且c[i-k]不為0,即從i元錢中刨去k元后剩下的錢數可以找開,
             則c[i]=c[i-k]+1
        若c[i]不為0,即已賦過值,則c[i]為c[i-k]+1和c[i]中較小的
*/
    public int coinChange(int[] coins, int amount) 
    {
        for(int i=0;i<coins.length;i++)
        {
            System.out.println(coins[i]);
        }
        int m=amount;
        int n=coins.length;
        int[] a=coins;
        int[] c=new int[m+1];//fu chu zhi 0
        if(amount==0)
            return 0;
       
        for(int i=0;i<n;i++)
        {
            if(a[i]<=m)
            {
                c[a[i]]=1;
            }
        
        }
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(i>a[j])
                {
                    if(c[i]==0&&c[i-a[j]]!=0)
                    {
                        c[i]=c[i-a[j]]+1;
                        System.out.println("c"+i+":"+c[i]);
                    } 
                    else
                    {
                        if(c[i-a[j]]!=0)
                        {
                            c[i]=c[i-a[j]]+1<c[i]?c[i-a[j]]+1:c[i];
                            System.out.println("c"+i+":"+c[i]);
                        }
                    }
                }
               
            }
        }
        if(c[m]==0)
        return -1;
        else
        return c[m];
        
    }
}

另一種更有效的方法
public int coinChange(int[] coins, int amount) {
    if (amount < 1) return 0;
    int[] dp = new int[amount + 1]; 
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;
    for (int coin : coins) {
        for (int i = coin; i <= amount; i++) {
            if (dp[i - coin] != Integer.MAX_VALUE) {
                dp[i] = Math.min(dp[i], dp[i - coin] + 1
); } } } return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount]; }