Problem p00614 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T &a, const T &b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T &b) { a = min(a, b); }

const double EPS = 1e-10;
typedef long long ll;
typedef pair<int, int> pint;

const int coin[] = {500, 100, 50, 10, 5, 1};
int min_coin(int change) {
  int res = 0;
  rep(i, 6) {
    int c = change / coin[i];
    res += c;
    change -= c * coin[i];
  }
  return res;
}
bool pint_eq(const pint &a, const pint &b) {
  cout << "hoge" << endl;
  return a.first == b.first;
}
int main() {
  int p, n[6];
  while (scanf("%d", &p), p) {
    rep(i, 6) scanf("%d", n + i);
    reverse(n, n + 6);

    vector<pint> d[7];
    d[0].push_back(pint(p, 0));

    int res = 1 << 25;
    rep(i, 6) {
      rep(j, d[i].size()) {
        int left = d[i][j].first;
        int use = d[i][j].second;
        for (int c = min(n[i], max(0, left / coin[i]));
             c <= n[i] && c * left - c * coin[i] >= -500; ++c) {
          d[i + 1].push_back(pint(left - c * coin[i], use + c));
        }
      }
      sort(all(d[i + 1]));
      d[i + 1].erase(unique(all(d[i + 1]), pint_eq), d[i + 1].end());
      rep(j, d[i + 1].size()) {
        int left = d[i + 1][j].first;
        int use = d[i + 1][j].second;
        if (left <= 0)
          min_swap(res, use + min_coin(-left));
      }
    }
    printf("%d\n", res);
  }
}

Fixed submission:
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T &a, const T &b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T &b) { a = min(a, b); }

const double EPS = 1e-10;
typedef long long ll;
typedef pair<int, int> pint;

const int coin[] = {500, 100, 50, 10, 5, 1};
int min_coin(int change) {
  int res = 0;
  rep(i, 6) {
    int c = change / coin[i];
    res += c;
    change -= c * coin[i];
  }
  return res;
}
bool pint_eq(const pint &a, const pint &b) { return a.first == b.first; }
int main() {
  int p, n[6];
  while (scanf("%d", &p), p) {
    rep(i, 6) scanf("%d", n + i);
    reverse(n, n + 6);

    vector<pint> d[7];
    d[0].push_back(pint(p, 0));

    int res = 1 << 25;
    rep(i, 6) {
      rep(j, d[i].size()) {
        int left = d[i][j].first;
        int use = d[i][j].second;
        for (int c = min(n[i], max(0, left / coin[i]));
             c <= n[i] && c * left - c * coin[i] >= -500; ++c) {
          d[i + 1].push_back(pint(left - c * coin[i], use + c));
        }
      }
      sort(all(d[i + 1]));
      d[i + 1].erase(unique(all(d[i + 1]), pint_eq), d[i + 1].end());
      rep(j, d[i + 1].size()) {
        int left = d[i + 1][j].first;
        int use = d[i + 1][j].second;
        if (left <= 0)
          min_swap(res, use + min_coin(-left));
      }
    }
    printf("%d\n", res);
  }
}