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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int coin[] = {1, 5, 10, 50, 100, 500};

int num[6];
int mm;
int p;
bool f[1000 * 1000];

int change(int sum) {
  int ret = 0;
  for (int i = 5; i >= 0; i--) {
    ret += sum / coin[i];
    sum %= coin[i];
  }
  return ret;
}

#define MAX (10000000)

void search(int sum, int i, int cc) {
  // printf("search(%d,%d,%d), mm=%d\\n",sum,i,cc,mm);
  if (sum >= 0) {
    int tmp = cc + change(sum);
    mm = min(tmp, mm);
  }

  if (i < 0)
    return;
  if (mm < cc)
    return;

  int cnt;
  if (sum < 0) {
    cnt = (-sum) / coin[i];
    if (cnt >= num[i])
      cnt = num[i];
  } else {
    cnt = 0;
  }
  for (int j = 0; j <= 6; j++)
    if (cnt + j <= num[i])
      search(sum + (cnt + j) * coin[i], i - 1, cc + cnt + j);
}

int main() {
  while (scanf("%d", &p), p) {
    int ans = 0;

    REP(i, 6) scanf("%d", &num[i]);
    mm = 0;
    memset(f, 0, sizeof(f));

    int sum = 0;
    for (int i = 5; i >= 0; i--) {
      int cnt = 0;
      while (sum < p && cnt < num[i]) {
        cnt++;
        sum += coin[i];
      }
      mm += cnt;
      if (sum >= p)
        break;
    }
    mm += change(sum - p);
    search(-p, 5, 0);
    printf("%d\\n", mm);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int coin[] = {1, 5, 10, 50, 100, 500};

int num[6];
int mm;

int change(int sum) {
  int ret = 0;
  for (int i = 5; i >= 0; i--) {
    ret += sum / coin[i];
    sum %= coin[i];
  }
  return ret;
}

#define MAX (10000000)

void search(int sum, int i, int cc) {
  // printf("search(%d,%d,%d), mm=%d\\n",sum,i,cc,mm);
  if (sum >= 0) {
    int tmp = cc + change(sum);
    mm = min(tmp, mm);
    return;
  }

  if (mm < cc)
    return;

  if (i < 5)
    search(sum, i + 1, cc);

  if (num[i] >= 0) {
    num[i]--;
    search(sum + coin[i], i, cc + 1);
    num[i]++;
  }
}

int main() {
  int p;
  while (scanf("%d", &p), p) {
    int ans = 0;

    REP(i, 6) scanf("%d", &num[i]);
    mm = 0;

    int sum = 0;
    for (int i = 5; i >= 0; i--) {
      int cnt = 0;
      while (sum < p && cnt < num[i]) {
        cnt++;
        sum += coin[i];
      }
      mm += cnt;
      if (sum >= p)
        break;
    }
    mm += change(sum - p);
    search(-p, 0, 0);
    printf("%d\\n", mm);
  }
  return 0;
}