Title description
There are n coins with different denominations, and the denomination of each coin is stored in the array T [1: n]. Now we need to use these denomination coins to find money. The number of coins of various denominations that can be used is stored in the array Coins [1: n]. For a given 1 ≤ n ≤ 10, the coin face value array T and the coin number array of various face value coins that can be used, and the money amount m, 0≤m≤20001, program to calculate the minimum number of coins for money m.
Input
Only 1 integer in the first line gives the value of n, and there are 2 numbers in each line from the second line, T [j] and Coins [j], respectively. The last line is the amount of money m to find.
Output
Minimum number of coins, output -1 when there is no solution
Sample input
3
1 3
2 3
5 3
18
Sample output
5
This question is a dynamic planning question. For a long time, I didn't understand how to start, so I solved the problem according to my own ideas:
- Sort the array from large to small, use fast sort;
- Then, in the array, determine whether the change number m is greater than the value of the coin, and whether the corresponding coin is used up;
- If the above conditions are met, the coin with this value is one of the change, m is subtracted from this value to get a new change;
- Repeat the above operation, if you can finally get m equal to 0, then output the minimum number of coins, otherwise, output -1.
First look at the code:
typedef struct {
int T;
int Coins;
}Mo;
bool cmp(Mo a, Mo b){
return a.T > b.T ;
}
int ChangeMaking(int m, int n, Mo *a){
sort(a,a+n,cmp);
int flag = 0;
for(int i = 0; i < n; i++){
while(a[i].Coins > 0 && m - a[i].T >= 0){
m -= a[i].T ;
flag ++;
a[i].Coins --;
}
}
if(flag != 0 && m == 0) return flag;
else return -1;
}
You do n’t think there ’s anything wrong, right? That's a big mistake . Look at this example:
Suppose the number of change m = 8, there are 1 5, 2 4 and 1 2. This example is simple. It can be seen that the minimum number of coins is 2 (2 4), but according to the above algorithm, there will be no solution, which contradicts the correct answer .
Therefore, we still honestly learn the algorithm of dynamic programming to solve this problem.
The following is the complete code .
Code
#include<iostream>
using namespace std;
int T[11],Coins[11];
int main(){
int n,m;
cin>>n;
for(int i = 1; i <= n; i++){
cin>>T[i]>>Coins[i];
}
cin>>m;
int dp[20001];
for(int i = 1; i < 20001; i++){
dp[i] = 101;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= Coins[i] ; j++ ){
for(int k = m; k >= T[i]; k --){
dp[k]=min(dp[k-T[i]] + 1,dp[k]);
}
}
}
if(dp[m] == 101) cout<<"-1"<<endl;
else cout<<dp[m]<<endl;
return 0;
}
Ideas
- Used dynamic programming algorithms;
- Detailed ideas for this question will be given in subsequent versions.
Recommended topics
If it helps you, remember to like it!