Problem p01088 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define INF 100000000
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
int n;
int p[101];
P dp[101][50001];

P max_get(P a, P b) {
  if (a.first > b.first) {
    return a;
  }
  if (a.first < b.first) {
    return b;
  }
  return (a.second <= b.second) ? a : b;
}

int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    for (int i = 0; i < n; i++) {
      scanf("%d", &p[i]);
    }
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= 500000; j++) {
        dp[i][j] = P(0, INF);
      }
    }
    dp[0][0] = P(0, 0);
    for (int i = 0; i < n; i++) {
      int need = (p[i] % 1000) - 500;
      if (need < 0)
        need += 1000;
      int oturi = 1000 - (p[i] % 1000);
      if (oturi == 1000)
        oturi = 0;
      for (int j = 0; j <= 50000; j++) {
        if (dp[i][j].second != INF) {
          dp[i + 1][j] = max_get(dp[i + 1][j], dp[i][j]);
          if (p[i] % 1000 < 500 && ((p[i] % 1000) != 0)) {
            P np = dp[i][j];
            np.first++;
            np.second += p[i];
            dp[i + 1][j + oturi - 500] =
                max_get(dp[i + 1][j + oturi - 500], np);
          } else {
            if (j >= need) {
              P np = dp[i][j];
              np.first++;
              np.second += p[i];
              dp[i + 1][j - need] = max_get(dp[i + 1][j - need], np);
            } else {
              P np = dp[i][j];
              np.second += p[i];
              dp[i + 1][j + oturi] = max_get(dp[i + 1][j + oturi], np);
            }
          }
        }
      }
    }
    int r1 = 0, r2 = 0;
    for (int i = 0; i <= 50000; i++) {
      if (dp[n][i].second != INF) {
        if (r1 == dp[n][i].first && r2 > dp[n][i].second) {
          r1 = dp[n][i].first;
          r2 = dp[n][i].second;
        }
        if (r1 < dp[n][i].first) {
          r1 = dp[n][i].first;
          r2 = dp[n][i].second;
        }
      }
    }
    printf("%d %d\n", r1, r2);
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define INF 100000000
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
int n;
int p[101];
P dp[101][50001];

P max_get(P a, P b) {
  if (a.first > b.first) {
    return a;
  }
  if (a.first < b.first) {
    return b;
  }
  return (a.second <= b.second) ? a : b;
}

int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    for (int i = 0; i < n; i++) {
      scanf("%d", &p[i]);
    }
    for (int i = 0; i <= n; i++) {
      for (int j = 0; j <= 50000; j++) {
        dp[i][j] = P(0, INF);
      }
    }
    dp[0][0] = P(0, 0);
    for (int i = 0; i < n; i++) {
      int need = (p[i] % 1000) - 500;
      if (need < 0)
        need += 1000;
      int oturi = 1000 - (p[i] % 1000);
      if (oturi == 1000)
        oturi = 0;
      for (int j = 0; j <= 50000; j++) {
        if (dp[i][j].second != INF) {
          dp[i + 1][j] = max_get(dp[i + 1][j], dp[i][j]);
          if (p[i] % 1000 < 500 && ((p[i] % 1000) != 0)) {
            P np = dp[i][j];
            np.first++;
            np.second += p[i];
            dp[i + 1][j + oturi - 500] =
                max_get(dp[i + 1][j + oturi - 500], np);
          } else {
            if (j >= need) {
              P np = dp[i][j];
              np.first++;
              np.second += p[i];
              dp[i + 1][j - need] = max_get(dp[i + 1][j - need], np);
            } else {
              P np = dp[i][j];
              np.second += p[i];
              dp[i + 1][j + oturi] = max_get(dp[i + 1][j + oturi], np);
            }
          }
        }
      }
    }
    int r1 = 0, r2 = 0;
    for (int i = 0; i <= 50000; i++) {
      if (dp[n][i].second != INF) {
        if (r1 == dp[n][i].first && r2 > dp[n][i].second) {
          r1 = dp[n][i].first;
          r2 = dp[n][i].second;
        }
        if (r1 < dp[n][i].first) {
          r1 = dp[n][i].first;
          r2 = dp[n][i].second;
        }
      }
    }
    printf("%d %d\n", r1, r2);
  }
  return 0;
}