Problem p01088 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
int n;
vi p;
pii dp[101][55555];

pii solve(int shop, int coin) {
  if (shop == n)
    return pii(0, 0);
  if (dp[shop][coin].first >= 0)
    return dp[shop][coin];
  pii res(0, 0);
  chmax(res, solve(shop + 1, coin));
  pii tmp;
  if (p[shop] % 1000 == 0) {
    if (coin >= 500) {
      tmp = solve(shop + 1, coin - 500);
      chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
    }
  } else if (p[shop] % 1000 > 500) {
    tmp = solve(shop + 1, coin + 1000 - p[shop] % 1000);
    chmax(res, pii(tmp.first, tmp.second - p[shop]));
    if (p[shop] % 1000 - 500 <= coin) {
      tmp = solve(shop + 1, coin - (p[shop] % 1000 - 500));
      chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
    }
  } else {
    tmp = solve(shop + 1, coin + 500 - p[shop] % 1000);
    chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
  }
  return res;
}

int main() {
  cin.sync_with_stdio(false);
  while (cin >> n, n) {
    p.resize(n);
    REP(i, n) cin >> p[i];
    REP(i, 101) REP(j, 55555) dp[i][j] = pii(-1, -1);
    pii ans = solve(0, 0);
    cout << ans.first << " " << -ans.second << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
int n;
vi p;
pii dp[101][55555];

pii solve(int shop, int coin) {
  if (shop == n)
    return pii(0, 0);
  if (dp[shop][coin].first >= 0)
    return dp[shop][coin];
  pii res(0, 0);
  chmax(res, solve(shop + 1, coin));
  pii tmp;
  if (p[shop] % 1000 == 0) {
    if (coin >= 500) {
      tmp = solve(shop + 1, coin - 500);
      chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
    }
  } else if (p[shop] % 1000 > 500) {
    tmp = solve(shop + 1, coin + 1000 - p[shop] % 1000);
    chmax(res, pii(tmp.first, tmp.second - p[shop]));
    if (p[shop] % 1000 - 500 <= coin) {
      tmp = solve(shop + 1, coin - (p[shop] % 1000 - 500));
      chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
    }
  } else {
    tmp = solve(shop + 1, coin + 500 - p[shop] % 1000);
    chmax(res, pii(tmp.first + 1, tmp.second - p[shop]));
  }
  return dp[shop][coin] = res;
}

int main() {
  cin.sync_with_stdio(false);
  while (cin >> n, n) {
    p.resize(n);
    REP(i, n) cin >> p[i];
    REP(i, 101) REP(j, 55555) dp[i][j] = pii(-1, -1);
    pii ans = solve(0, 0);
    cout << ans.first << " " << -ans.second << endl;
  }
  return 0;
}