Problem p01088 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ALL(A) A.begin(), A.end()
#define RALL(A) A.rbegin(), A.rend()
typedef long long LL;
typedef pair<int, int> P;
const LL mod = 1e9 + 7;
const LL LINF = 1LL << 62;
const LL INF = 1 << 17;

P dp[101][50501];
P pmax(P p, P q) {
  if (p.fs > q.fs)
    return p;
  else if (p.fs == q.fs)
    return (p.sc < q.sc ? p : q);
  else
    return q;
}

int main() {
  int N;
  while (cin >> N) {
    if (!N)
      return 0;
    int p[N];
    for (int i = 0; i < N; i++) {
      cin >> p[i];
    }
    for (int i = 0; i <= N; i++) {
      for (int j = 0; j < 50001; j++) {
        if (j == 0)
          dp[i][j] = mp(0, 0);
        else
          dp[i][j] = mp(-1, INF);
      }
    }
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 50001; j++) {
        if (dp[i][j].fs == -1) {
          continue;
        }
        P d = dp[i][j];
        dp[i + 1][j] = pmax(dp[i + 1][j], d);
        d.sc += p[i];
        int res = (1000 - p[i] % 1000) % 1000;
        dp[i + 1][j + res] = pmax(dp[i + 1][j + res], d);
        if (res >= 500) {
          d.fs++;
          res -= 500;
          dp[i + 1][j + res] = pmax(dp[i + 1][j + res], d);
        } else {
          d.fs++;
          res = 500 - res;
          if (res <= j)
            dp[i + 1][j - res] = pmax(dp[i + 1][j - res], d);
        }
      }
    }
    P ans = mp(0, LINF);
    for (int i = 0; i <= 50000; i++) {
      ans = pmax(ans, dp[N][i]);
    }
    cout << ans.fs << " " << ans.sc << endl;
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define ALL(A) A.begin(), A.end()
#define RALL(A) A.rbegin(), A.rend()
typedef long long LL;
typedef pair<int, int> P;
const LL mod = 1e9 + 7;
const LL LINF = 1LL << 62;
const LL INF = 1 << 17;

P dp[102][50501];
P pmax(P p, P q) {
  if (p.fs > q.fs)
    return p;
  else if (p.fs == q.fs)
    return (p.sc < q.sc ? p : q);
  else
    return q;
}

int main() {
  int N;
  while (cin >> N) {
    if (!N)
      return 0;
    int p[N];
    for (int i = 0; i < N; i++) {
      cin >> p[i];
    }
    for (int i = 0; i <= N; i++) {
      for (int j = 0; j < 50001; j++) {
        if (j == 0)
          dp[i][j] = mp(0, 0);
        else
          dp[i][j] = mp(-1, INF);
      }
    }
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 50001; j++) {
        if (dp[i][j].fs == -1) {
          continue;
        }
        P d = dp[i][j];
        dp[i + 1][j] = pmax(dp[i + 1][j], d);
        d.sc += p[i];
        int res = (1000 - p[i] % 1000) % 1000;
        dp[i + 1][j + res] = pmax(dp[i + 1][j + res], d);
        if (res >= 500) {
          d.fs++;
          res -= 500;
          dp[i + 1][j + res] = pmax(dp[i + 1][j + res], d);
        } else {
          d.fs++;
          res = 500 - res;
          if (res <= j)
            dp[i + 1][j - res] = pmax(dp[i + 1][j - res], d);
        }
      }
    }
    P ans = mp(0, LINF);
    for (int i = 0; i <= 50000; i++) {
      ans = pmax(ans, dp[N][i]);
    }
    cout << ans.fs << " " << ans.sc << endl;
  }
  return 0;
}