最少貨幣數問題

題目:

給定數組arr, arr中所有的值都爲正數且不重複。每個值代表一中面值的貨幣,每種面值的貨幣可以使用任意張,再給定一個整數aim代表要找的錢數,求組成aim的最少貨幣數。

思路 :

採用動態規劃的思想來解此題。首先設定dp[i][j]數組,i的意思是當前的最大貨幣數,j的意思是目標貨幣數。因此dp[i][j]的意思就是使用最大貨幣i可以組成貨幣j的最少貨幣數。假設現在有{10,5,2,1}的貨幣,要求找出15元。當手裏有1元時,無法找出15元,但是當最大的貨幣數爲5元時,可以有5+5+5這一種情況,貨幣數最少爲3.
設此時的dp[i][j]爲MaxValue(Integer所能表示的最大值)。依次遍歷每一種貨幣值和目標錢數。其中有一個重要的公式:

dp[i][j] = min{dp[i-1][j],dp[i][j-amount]+1};

即當前手裏的貨幣值最大的爲i時,目標金額減去i的數值amount,計算最大爲i求定額j-amount的數目。該值之前曾計算出來。注意需要在最終解上+1。同時還要和i-1情況下的貨幣值(也可以組成目標j的貨幣值)做一個對比,取最小值。

解題代碼:

public int Solution(int [] coins,int aim){
        if(coins == null || aim<=0)
            return 0;
        //動態規劃數組
        int [][] dp = new int [coins.length][aim+1];
        int maxvalue = Integer.MAX_VALUE;

        //初始化dp數組
        for(int i=1;i<=aim;i++){
            dp[0][i] = maxvalue;
            if(i>=coins[0] && dp[0][i-coins[0]] != maxvalue){
                dp[0][i] = dp[0][i-coins[0]]+1;
            }
        }

        //計算每個數組所需的最小貨幣數
        int left = 0;
        for(int i=1;i<coins.length;i++){
            for(int j=1;j<aim+1;j++){
                left = maxvalue;
                if(j>=coins[i]&& dp[i][j-coins[i]] != maxvalue){
                    left = dp[i][j-coins[i]]+1;
                }
                dp[i][j] = left<dp[i-1][j]?left:dp[i-1][j];
            }
        }
        return dp[coins.length-1][aim];
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章