One, the problem description
Given a set of coins, find a minimum number of coins to find change n.
For example, the coins that can be used for change are: 1, 3, 4 the amount to be found is 6. Change with two denominations of 3 coins and a minimum of 2 coins. And not 4,1,1 .
Therefore, summarize the characteristics of the problem: ① coins can be reused multiple times. ② in some cases, the problem can be solved by greedy algorithms. For specific reference: the correctness of a greedy algorithm for a coin-changing problem
Second, dynamic programming analysis
For better analysis, the problem is defined first: The face value of the coin used for change is stored in an array. As follows:
Coinsvalues[i] denotes the par value of the first coin. Like what
The denomination of the first coin
1 1
2 3
3 4
The amount of money to change is N (n=6 in the example above)
In order to solve the problem, the average value of the 1th coin is 1.
Consider the optimal substructure of the problem: set c[i,j] for No. 0, 1, .... I coin the minimum number of coins required to make a change to the amount of Money J.
I means the number of coins available, j means the change that needs to be recovered.
The first coin has two options: use it for change and not change it. Therefore, the optimal solution for C[I,J] is as follows:
c[i,j]= Min{c[i-1,j], C[i, J-coinsvalues[i]] + 1} wherein,
C[I-1,J] means that the minimum number of coins required to make a change to the amount of J is not used to find the first coin.
c[i, J-coinsvalues[i]] + 1 means the minimum number of coins needed to make a change to the amount of J when using the I coin to find the zero. As a result of the use of the first coins, so the number of coins to be increased by 1
C[I,J] The one that takes the smaller value of both.
In addition, for special case analysis ( special Case 1):
C[0][j]=integer.maxvalue, because the amount of money for a J change, but the type of coin can be 0, which is obviously impossible to do (unless the robber:))
C[i][0]=0, because, the amount of money for change, can be used to change the coin type has I species, the amount of 0 ah, how to find Ah, find an egg ah.
In fact, the boundary conditions are based on specific problems. DP too broad, understand not deep.
In addition, there is a special case ( special case 2), that is: Coinsvalues[i] > J
This indicates that the value of the first coin is greater than the amount of J, this can not use the first coin to change Ah, (owe you 5 yuan, but find you a hundred dollar bills) or you lose (the loss is a blessing Ah ^~^...or kill chicken with Sledgehammer!!!)
With this feature transfer equation:c[i,j]= min{c[i-1,j], C[i, J-coinsvalues[i]] + 1} , it's good to write code.
Third, Java code implementation
1 /**2 * 3 * @paramcoinsvalues can be used to change the coin coinsvalues.length is the type of coin4 * @paramn The change to be found5 * @return Minimum number of coins6 */7 Public Static intChargeint[] coinsvalues,intN) {8 int[] C =New int[Coinsvalues.length + 1] [n + 1];9 Ten //Special Case 1 One for(inti = 0; I <= coinsvalues.length; i++) AC[i][0] = 0; - for(inti = 0; I <= N; i++) -C[0][i] =Integer.max_value; the - for(intJ_money = 1; J_money <=n; j_money++) - { - + for(intI_coinkinds = 1; I_coinkinds <= coinsvalues.length; i_coinkinds++) - { + if(J_money < coinsvalues[i_coinkinds-1])//Special Case 2,coinsvalues array subscript is starting from 0, c[][] array subscript is calculated starting from 1 A { atC[i_coinkinds][j_money] = c[i_coinkinds-1][j_money];//can only use 1th ... (i-1) Coins in a coin - Continue; - } - - //the number of choices for each question---Select one of the smaller - if(C[i_coinkinds-1][j_money] < (C[i_coinkinds][j_money-coinsvalues[i_coinkinds-1]] +1)) inC[i_coinkinds][j_money] = c[i_coinkinds-1][j_money]; - Else toC[i_coinkinds][j_money] = c[i_coinkinds][j_money-coinsvalues[i_coinkinds-1]] +1; + } - } the returnC[coinsvalues.length][n]; *}
① Line 28th-line 20 is the representation of the state transition equation.
The For loop on line 16th-line 19th of ② is the bottom-up idea of dynamic planning.
Complexity analysis: From the For loop of code 19-20 lines, the time complexity is O (MN), M is the number of coins available, n is the amount of change to be found
Theoretically, the time complexity of DP (Dynamic programming) is the number of sub-problems multiplied by the number of available choices for each sub-problem. Obviously, this has MN sub-problem, each sub-problem has two options (select I coins and do not select I coin).
have been very curious DP through the column of an equation to solve a problem, in fact, from 16-19 lines of the For loop, the loop subscript is from small to large, indicating that it first solve the sub-problem, and then the original problem to solve.
Four, references
The correctness proof of some greedy algorithm for changing coins problem
The difference and relation between dynamic programming and greedy algorithm from the viewpoint of activity selection
http://haolloyin.blog.51cto.com/1177454/352115
Five, complete code
Importjava.util.Arrays; Public classDpcharge {/** * * @paramcoinsvalues can be used to change the coin coinsvalues.length is the type of coin *@paramn The change you are looking for@return */ Public Static intChargeint[] coinsvalues,intN) { int[] C =New int[Coinsvalues.length + 1] [n + 1]; //Special Case 1 for(inti = 0; I <= coinsvalues.length; i++) c[i][0] = 0; for(inti = 0; I <= N; i++) c[0][i] =Integer.max_value; for(intJ_money = 1; J_money <=n; j_money++) { for(intI_coinkinds = 1; I_coinkinds <= coinsvalues.length; i_coinkinds++) { if(J_money < coinsvalues[i_coinkinds-1])//Special Case 2{C[i_coinkinds][j_money]= C[i_coinkinds-1][j_money]; Continue; } //the number of choices for each question---Select one of the smaller if(C[i_coinkinds-1][j_money] < (C[i_coinkinds][j_money-coinsvalues[i_coinkinds-1]] +1)) C[i_coinkinds][j_money]= C[i_coinkinds-1][j_money]; ElseC[i_coinkinds][j_money]= C[i_coinkinds][j_money-coinsvalues[i_coinkinds-1]] +1; } } returnC[coinsvalues.length][n]; } Public Static voidMain (string[] args) {int[] coinsvalues = {1,3,4}; Arrays.sort (coinsvalues);//need to sort the array, or it will cross ..... intn = 6; intMincoinsnumber =Charge (coinsvalues, n); System.out.println (Mincoinsnumber); }}
The dynamic programming realization of coin change problem