
The sake of explanation, suppose the coins are 1c, 5c, 10c, 50c and 100c. There are some observations that can be made (and obviously generalised to other sets of coins):
Combining the observations and assumptions above yields the following algorithm to determine what to pay in the given week.
To speed things up, it is worth exploiting the fact that the set of coins used in one week is likely to the same the next week. Each time a new coin-set is built, some simple calculations show how many weeks it is valid for (i.e. until one of the coins runs out), and this number of weeks can be added straight on to the answer without going through the construction for every week.
Here is the solution Croatian senior Jurica Cerovec:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in ("allow.in");
ofstream out("allow.out");
int n,c;
vector <pair <int, int> > coins;
int main() {
in >> n >> c;
coins.clear();
for (int i = 0; i<n; i++) {
int a, b;
in >> a >> b;
coins.push_back (make_pair (a, b));
}
sort (coins.begin(), coins.end());
bool moze=true;
int w=0;
while (moze) {
int suma = c;
moze = false;
for (int i = coins.size()-1; i >= 0; i--) {
while (coins[i].second>0 && suma-coins[i].first >= 0) {
coins[i].second--;
suma -= coins[i].first;
}
}
for (int i = 0; i < coins.size (); i++)
if (coins[i].second > 0 && suma > 0) {
coins[i].second--;
suma -= coins[i].first;
break;
}
if (suma <= 0) moze=true;
if (moze) w++;
}
out << w << endl;
return 0;
}