Skip to content

Instantly share code, notes, and snippets.

@browny
Created March 31, 2013 08:32
Show Gist options
  • Save browny/5279992 to your computer and use it in GitHub Desktop.
Save browny/5279992 to your computer and use it in GitHub Desktop.
Given a list of N coins, their values being in an array A[], return the minimum number of coins required to sum to S (you can use as many coins you want). If it's not possible to sum to S, return -1
#include <cmath>
#include <vector>
#include <iostream>
using namespace std;
// greedy
int minCoins_greedy(vector<int> a, int sum) {
sort(a.begin(), a.end(), greater<int>()); // sorted in descending order
a.erase(unique(a.begin(), a.end()), a.end()); // remove duplicates
int ret;
for (int i = 0; i < a.size(); i++) {
int remains = sum - a[i];
//cout << sum << " - " << a[i] << " = " << remains << endl;
if (remains > 0) {
ret = minCoins_greedy(a, remains);
//cout << "ret: " << ret << endl;
if (ret > 0) {
cout << a[i] << " + ";
return ++ret;
}
} else if (remains == 0) {
cout << a[i] << " + ";
return 1;
}
}
return -1;
}
// dynamic programming
#define MIN(a, b) ((a) == -1) ? (b) : min((a),(b));
int minCoins(vector<int> S, int sum) {
int setSize = S.size();
int count[setSize+1][sum+1];
// For sum = 0, do not need any coins
for (int i = 0; i < setSize+1; i++)
count[i][0] = 0;
// For empty set, it is impossible to sum to >0
// use -1 represents fail
for (int j = 1; j < sum+1; j++)
count[0][j] = -1;
/*
* cost func:
* c(n, m) = min( c(n-1, m) , c(n, m-M[n]) + 1 )
* ^^^^^^^^^ ^^^^^^^^^^^^^^^^
* don't take take M[n]
*/
for (int i = 1; i < setSize+1; i++) {
for (int j = 1; j < sum+1; j++) {
if ((j - S[i-1]) >= 0) {
count[i][j] = MIN(count[i-1][j], count[i][j-S[i-1]] + 1);
}
else
count[i][j] = count[i-1][j];
}
}
// uncomment this code to print table
for (int i = 0; i <= setSize; i++)
{
for (int j = 0; j <= sum; j++)
printf ("%4d", count[i][j]);
printf("\n");
}
return count[setSize][sum];
}
int main() {
// Input to a sorted vector
int size, sum;
cout << "input 'size' and 'sum'" << endl;
cout << "ex: 4 63" << endl;
cin >> size >> sum;
cout << "input coins" << endl;
cout << "ex: 1 10 30 40" << endl;
int* arr;
arr = new int[size];
for (int i = 0; i < size; i++) {
int c;
cin >> c;
arr[i] = c;
}
vector<int> vecArr(arr, arr+size);
// Output
int out = minCoins(vecArr, sum);
//int out = minCoins_greedy(vecArr, sum);
cout << endl;
if (out > 0)
cout << "Minimum " << out << " coins needed" << endl;
else
cout << "Impossible" << endl;
delete[] arr;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment