找零錢的兩種方法

2021-06-29 09:42:50 字數 2137 閱讀 2519

有時候,去便利店買幾塊錢的東西,但沒有零錢,只能給他們一張100的,他們可能找給我一沓10塊的和幾枚硬幣。我不喜歡這麼多的零錢,要知道,錢越零散,散失地就越快,我希望找給我的零錢張數最少。

如何找出最少數目(錢的張數)的零錢呢?這個問題看起來很簡單,假設要用50、20、10、5、1(元)找出87元來,任何人都可以簡單地得出:1張50、1張20、1張10、1張5和2張1元就可以滿足。可以用**表示出來:

public

static

int makechange(int money, int changes)

}return result;

}

輸入money=87,changes=,則結果為:。這種方法的特點是:從最大額的零錢開始,逐次湊出需要的數額來,不關心總的數目是否真的是最小。這樣的演算法也形象地稱為「貪心演算法」,而找出最少數目的零錢的問題稱為「最優化問題」。在某些情況下,貪心演算法未必能得到最優的解,比如恰好10元和5元沒有了,只剩下50、20和1元,這時要找出60元,需要1張50和10張1元,而實際上只要3張20就可以了。如果各種零錢是充足的,則可以證明貪心演算法得到的解也是最優解。

零錢的集合是 ,記為c。對於乙個特定的數額n,它的最優解記為q。那麼q中至多有2個20,因為如果有3個的話,可以用1張50和1張10來代替3張20;如果有2張20,則不能有10元的,否則可以用1張50來代替,同理最多有1張5和4張1,這樣可以確定如果有2張20,則在q中小於50的零錢總數在40和49之間;同理如果只有1張20的,則最多有1張10、1張5和4張1,總數在20和39之間;如果沒有20,則最多有1張10、1張5和4張1,總數在0和19之間。總之,在最優解中,小於50的零錢總數在0到49之間【結論1】。有了這個結論,下面來證明上述問題中,貪心演算法得到的解也是最優解。

還是使用上面的標記:零錢集合c,數額n,最優解q,假設貪心演算法得到的解是q』。用q50表示q中50元的個數,q』50表示q』中50元的個數,由於q』中包含盡可能多的50,所以q50<=q』50,由【結論1】,q50如果各種零錢充足,現在是沒問題了,如果某些零錢沒有了,貪心演算法未必能得到最優解,這時該如何求解呢?為簡化問題,我們假設1元的錢總是充足的,所以解總是存在的。對於數額n,可做如下考慮:

1)如果n = 1,則用1個1元來找零,這就是最優解;

2)如果n > 1,則對於每個可能的值i,分別找出i元和n-i元來。

通過這樣的遞迴,可以找出所有可能的解來,這樣就可以找到最優解來了。不過該方法效率不高,因為存在大量冗餘的計算,比如要找出60元,中間需要計算59,要計算59則一定需要計算58。。。而且這些計算要重複多次,這種情形稱為「遞迴**」。這裡很像使用遞迴來求解fibonacci數列一樣,存在很大的效率問題。在優化fibonacci數列的計算時,一種方法是將計算過的值存放在乙個陣列裡,以供重複使用,這裡也可以採用這樣的思路。

public

static

void makechangedynamically(int money, int changes, int changesused, int lastchange)

//如果使用這個數額來找所需要的數目更小

if (changesused[dollars - changes[j]] + 1

< minchangecount)

}changesused[dollars] = minchangecount;

lastchange[dollars] = newchange;}}

這個方法屬於動態規劃的應用。假設現在要找的數額為67,changes = ,changesused陣列會儲存從1到66之間的數值分別需要多少張零錢,在求解67的時候,會這樣考慮:對於changes的每個數值,將67拆分為1+66,5+62,10+57,20+47,50+17,由於66、62、57、47、17這些值都已計算過,所以可以迅速得出對於67找零需要幾張零錢;同時lastchange陣列儲存了從1到66之間的數值的最優解中,它們所使用的最後一張零錢是什麼,這樣回推過去,不但可以知道用幾張零錢,還可以知道這些零錢的數額分別是什麼。

雖然如此,在日常生活中找零錢的時候,兩種方法都不需要,心算即可:)

參考:《離散數學及其應用》

《資料結構與問題求解》

anders cui

出處:

找零錢的兩種方法

有時候,去便利店買幾塊錢的東西,但沒有零錢,只能給他們一張100的,他們可能找給我一沓10塊的和幾枚硬幣。我不喜歡這麼多的零錢,要知道,錢越零散,散失地就越快,我希望找給我的零錢張數最少。如何找出最少數目 錢的張數 的零錢呢?這個問題看起來很簡單,假設要用50 20 10 5 1 元 找出87元來,...

找零錢問題

問題描述 我們知道人民幣有1 2 5 10 20 50 100這幾種面值。現在給你n 1 n 250 元,讓你計算換成用上面這些面額表示且總數不超過100張,共有幾種。比如4元,能用4張1元 2張1元和1張2元 2張2元,三種表示方法。輸入有多組,每組一行,為乙個整合n。輸入以0結束。輸出該面額有幾...

找零錢 貪心

現 在有1,2,5,10,20,50,100面值的人名幣若干。你的任務就是用最少的張數來找錢。如需要找23元,我們用一張20,一張2元,一張1元即可。所以3張就是最少的張數。description 輸入多組資料,第一行n n 100 表示有多少組錢需要找,第2 n 1行,輸入要找的錢m m 0 in...