There are n coins with different denominations. The denominations of each coin are stored in the array T [1: N. Now we need to use coins with these denominations to find money. The number of coins with various denominations that can be used is stored in the array coins [1: N. For any amount of money 0 ≤ m ≤ 20001, design a method to find money m with the minimum coin. |
|
|
We use an improved greedy algorithm to solve the problem of the least coin.
From the greedy algorithm, we can find money with a combination of coins with a large face value, which can minimize the number of coins used. The greedy algorithm can always obtain an approximate optimal solution for solving the problem of the least coin.
This algorithm uses the greedy policy to enumerate all the approximate optimal solutions, and then finds the optimal solution.
Find an approximate optimal solution group
For example, five coins with 9 points and five coins with 8 points,
For 8 coins with a nominal value of 2, you need 25 cents.
Set the money to m, the coin type to N, and T [I] (0 <I <= N) to the coin's face value, c [I] indicates the number of coins with various denominations that can be used, and K [I] indicates the maximum number of coins with the I-th denominations.
(K [I] = min {M/T [I], C [I]})
(1) Order coins by their nominal values
9 8 2
(2) Division by nominal value type
In each case, the first coin has different denominations, and the remaining coins are listed in ascending order of denominations.
Divided into three cases: 982,892,298.
Corresponding K [I]: K [0] = 3, K [1] = 3, K [2] = 8
The approximate optimal solution group is 9: 1, 8: 2; 9: 1, 8: 1, 2: 4; 9: 1, 2: 8.
Algorithm Optimization
1. In the process of finding the optimal combination, some situations may not be considered. For example, in the above example
2. In the case that the coin with a small face value is the first, when looking for the optimal combination, there are two situations:
A. the number of coins used is much larger than the number of coins with a large nominal value (such as 9 and 8.
B. The found combination is the same as the previous one.
Pruning in programs
If K [I] is no larger than mincount, the greedy algorithm is used to find the approximate optimal combination.
In the preceding example, the initial value of mincount is set to maxint.
K [0] = 3 <mincount, greedy selection, and put the best result in mincount = 3;
K [1] = 3 <= mincount = 3, greedy selection;
K [2] = 8> mincount = 3, then pruning
This can effectively reduce the scale of the problem.
Advantages and disadvantages of this algorithm
1. When the coin's face value is large, the execution efficiency will be improved (because K [I] becomes smaller ).
2. When the coin face value is small, the problem scale will become very large.
3. No redundancy is eliminated.
There are still many points worth further exploring about this algorithm.
4. Scale of the Algorithm
(1) Order the coin nominal value, O (nlogn ).
(2) finding the best combination of coins
N × Σ K [I]. If k = (Σ K [I])/N, O (kN * 2)
The scale of this algorithm is
O (nlogn) + O (kN * 2) = O (kN * 2)
This algorithm still has vulnerabilities because it uses greedy options.
The complete program code is as follows: # Include <stdio. h> # Include <fstream. h> # Include <stdlib. h> Int N, money; Struct ctype { Int value; Int coin; }; Template <class type> Void make2darray (type ** & X, int rows, int Cols) { X = new type * [rows]; For (INT I = 0; I <rows; I ++) X [I] = new type [Cols]; } Void swap (ctype & A, ctype & B) { Ctype temp; Temp =; A = B; B = temp; } Int partition (ctype array [], int P, int R) { Int I, J; Ctype key; I = P; J = R + 1; Key = array [p]; While (true) { While (array [++ I]. value <key. value ); While (array [-- J]. value> key. value ); If (I> = J) break; Swap (array [I], array [J]); } Array [p] = array [J]; Array [J] = key; Return J; } Void quicksort (ctype array [], int P, int R) { Int Q; If (P <R) { Q = partition (array, P, R ); Quicksort (array, P, q-1 ); Quicksort (array, q + 1, R ); } } Void main () { Ifstream input ("input.txt "); Ofstream output ("output.txt "); Input> N; Int * coins = new int [n + 1]; Ctype * t = new ctype [n + 1]; For (INT I = 1; I <= N; I ++) { Input> T [I]. value; Input> T [I]. coin; } Input> money; Quicksort (T, 1, n ); /* For (I = 1; I <= N; I ++) { Coins [I] = T [I]. coin; }*/ Int max = 0; For (I = 1; I <= N; I ++) MAX + = T [I]. coin; Max + = 10; Int * min = new int [money + 1]; Min [0] = 0; Int ** cnum; Make2darray (cnum, money + 1, n + 1 ); For (I = 0; I <= money; I ++) For (Int J = 1; j <= N; j ++) Cnum [I] [J] = 0; If (T [1]. value = 1) {Min [1] = 1; cnum [1] [1] = 1 ;} Else Min [1] = max; Int J = 2; While (j <= money) { Min [J] = max; I = 1; While (I <= N) & (j> = T [I]. Value )) { Int coinumber = cnum [J-T [I]. value] [I]; Coinumber ++; If (Min [J]> 1 + min [J-T [I]. value]) & (coinumber <= T [I]. Coin )) { For (int K = 1; k <= N; k ++) cnum [J] [k] = cnum [J-T [I]. value] [k]; Cnum [J] [I] ++; Min [J] = 1 + min [J-T [I]. value]; } I ++; } J ++; } If (Min [money]! = Max) Output <min [money]; Else output <-1; } |
|
|