【題目】
給定陣列arr,arr中所有的值都為正數且不重複。
每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,
再給定乙個整數aim代表要找的錢數,求組成aim的最少貨幣數。
【舉例】
arr=[5,2,3],aim=20。
4張5元可以組成20元,其他的找錢方案都要使用更多張的貨幣,所以返回4。
arr=[5,2,3],aim=0。不用任何貨幣就可以組成0元,返回0。
arr=[3,5],aim=2。根本無法組成2元,錢不能找開的情況下預設返回-1。
【解答】
原問題的經典動態規劃方法。如果arr的長度為n,
生成行數為n、列數為aim+1的動態規劃表的dp。
dp[i][j]的含義是,在可以任意使用arr[0..i]貨幣的情況下,
組成j所需的最小張數。根據這個定義,dp[i][j]的值按如下方式計算:
1.dp[0..n-1][0]的值(即dp矩陣中第一列的值)表示找的錢數為0時需要的最少張數,
錢數為0時,完全不需要任何貨幣,所以全設為0即可。
2.dp[0][0..aim]的值(即dp矩陣中第一行的值)表示只能使用arr[0]貨幣的情況下,
找某個錢數的最小張數。比如,arr[0]=2,那麼能找開的錢數為2,4,6,8,...
所以令dp[0][2]=1,dp[0][4]=2,dp[0][6]=3,...第一行其他位置所代表的錢數一律找不開,
所以一律設為32位整數的最大值,我們把這個值記為max。
3.剩下的位置依次從左到右,再從上到下計算。
假設計算到位置(i ,j),dp[i][j]的值可能來自下面的情況。
● 完全不使用當前貨幣arr[i]情況下的最少張數,即dp[i-1][j]的值。
● 只使用1張當前貨幣arr[i]情況下的最少張數,即dp[i-1][j-arr[i]]+1。
● 只使用2張當前貨幣arr[i]情況下的最少張數,即dp[i-1][j-2*arr[i]]+2。
● 只使用3張當前貨幣arr[i]情況下的最少張數,即dp[i-1][j-3*arr[i]]+3。
所有的情況中,最終取張數最小的。
所以 dp[i][j]=min
=>
dp[i][j]=min}
=>
dp[i][j]=min}
又有min =>
dp[i][j-arr[i]],
所以,最終有:dp[i][j]=min。
如果j-arr[i]<0,即發生越界了,說明arr[i]太大,用一張都會超過錢數j,
令dp[i][j]=dp[i-1][j]即可。具體過程請參看如下**中的mincoins1方法,
整個過程的時間複雜度與額外空間複雜度都為o(n×aim),n為arr的長度。
換錢最少貨幣數
給定陣列arr,arr中所有的值都為正數且不重複。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,在給定乙個整數aim代表要找的錢數,求組成aim的最少貨幣數。public class mincoins int len arr.length int max integer.max value...
換錢的最少貨幣數
題目一 給定陣列arr,arr中所有的值都為正數。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定乙個整數aim代表要找的錢數,求組成aim的最少貨幣數。如 arr 5,2,3 aim 20.最少需要4張 解題思路 經典動態規劃一般分為3部,先求dp i j 矩陣中第一列的值,然後求d...
換錢的最少貨幣數
換錢的最少貨幣數 給定陣列arr,arr中所有的值都為正整數且不重複。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定乙個 aim,代表要找的錢數,求組成aim的最少貨幣數。輸入描述 輸入包括兩行,第一行兩個整數n 0 n 1000 代表陣列長度和aim 0 aim 5000 第二行n...