Problem p01132 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int T = 4;
const int INF = 1e9;

int cost[4] = {10, 50, 100, 500}, C, coins[4];

vector<int> check(int c) {
  vector<int> res(T);
  int d = abs(c - C);
  for (int i = T - 1; i >= 0; --i) {
    res[i] = d / cost[i];
    d %= cost[i];
  }
  return res;
}

int main() {
  bool f = false;
  while (cin >> C && C) {
    if (f)
      cout << endl;
    f = true;
    int sum = 0;
    REP(i, T) {
      cin >> coins[i];
      sum += cost[i] * coins[i];
    }
    vector<int> res = check(sum);
    // cout <<sum <<endl;
    // REP(i, T) cout <<coins[i] <<", "; cout <<endl;
    // REP(i, T) cout <<res[i] <<", "; cout <<endl;
    REP(i, T)
        if (coins[i] - res[i] > 0) cout << cost[i] << " " << coins[i] - res[i]
                                        << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int T = 4;
const int INF = 1e9;

int N, ans, c[4];
vector<int> ans_v;
map<int, vector<int>> r;

int check(vector<int> &v, vector<int> &used, int sum) {
  int tmp = 0;
  REP(i, T) tmp += v[i];
  sum -= N;
  REP(i, T) {
    if (used[i] > 0 && r[sum][i] > 0)
      return -1;
    tmp += r[sum][i];
  }
  if (tmp < ans) {
    ans = tmp;
    ans_v = used;
  }
  return tmp;
}

void dfs(vector<int> &v, vector<int> &used, int sum, set<vector<int>> &S,
         map<int, int> &closed) {
  // cout <<"==========" <<endl;
  // cout <<sum <<endl;
  // REP(i, T) cout <<v[i] <<", "; cout <<endl;
  // REP(i, T) cout <<used[i] <<", "; cout <<endl;
  int f = -1;
  if (sum >= N)
    f = check(v, used, sum);
  if (f != -1 && closed.find(sum) != closed.end() && closed[sum] <= f)
    return;
  closed[sum] = f;
  REP(i, T) {
    if (!v[i])
      continue;
    v[i] -= 1;
    used[i] += 1;
    if (S.find(used) == S.end()) {
      S.insert(used);
      dfs(v, used, sum + c[i], S, closed);
    }
    v[i] += 1;
    used[i] -= 1;
  }
}

int main() {
  c[0] = 10;
  c[1] = 50;
  c[2] = 100;
  c[3] = 500;
  for (int i = 0; i <= 13200; i += 10) {
    int sum = i;
    vector<int> tmp(T);
    for (int j = T - 1; j >= 0; --j) {
      tmp[j] = sum / c[j];
      sum %= c[j];
    }
    r[i] = tmp;
  }
  bool f = false;
  while (cin >> N && N) {
    if (f)
      cout << endl;
    f = true;
    ans = INF;
    vector<int> v(T), used(T, 0);
    REP(i, T) cin >> v[i];
    set<vector<int>> S;
    map<int, int> closed;
    dfs(v, used, 0, S, closed);
    REP(i, T) if (ans_v[i]) cout << c[i] << " " << ans_v[i] << endl;
  }
  return 0;
}