Problem p01088 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <utility>
#include <vector>

using namespace std;
struct Info {
  int mai;
  int cost;
  bool operator<(const Info &i) const {
    return (mai != i.mai) ? mai > i.mai : cost < i.cost;
  }
  bool operator==(const Info &i) const {
    return mai == i.mai and cost == i.cost;
  }
  Info operator+(const Info &i) const {
    return Info{mai + i.mai, cost + i.cost};
  }
};
constexpr int MAX = 100;
constexpr int RES = 49900;
constexpr int INF = 1 << 30;
const Info IINF = Info{0, INF};
Info dp[MAX + 1][RES + 1];

int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) {
      break;
    }
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
      cin >> p[i];
    }

    for (int i = 0; i <= MAX; i++) {
      for (int j = 0; j <= RES; j++) {
        dp[i][j] = IINF;
      }
    }
    dp[0][0] = Info{0, 0};

    for (int i = 0; i < n; i++) {
      for (int j = 0; j <= RES; j++) {
        if (not(dp[i][j] == IINF)) {
          const int price = p[i] % 1000;
          dp[i + 1][j] = min(dp[i + 1][j], dp[i][j]);
          int rest = j - price;
          for (int m = 0; m < 2 and m * 500 <= rest; m++) {
            dp[i + 1][rest - m * 500] =
                min(dp[i + 1][rest - m * 500], dp[i][j] + Info{m, p[i]});
          }
          if (price != 0) {
            rest = 1000 + j - price;
            for (int m = 0; m < 2 and m * 500 <= rest; m++) {
              dp[i + 1][rest - m * 500] =
                  min(dp[i + 1][rest - m * 500], dp[i][j] + Info{m, p[i]});
            }
          }
        }
      }
    }

    Info mini = IINF;
    for (int j = 0; j <= RES; j++) {
      mini = min(mini, dp[n][j]);
    }
    cout << mini.mai << " " << mini.cost << endl;
  }
  return 0;
}

Fixed submission:
#include <iostream>
#include <utility>
#include <vector>

using namespace std;
struct Info {
  int mai;
  int cost;
  bool operator<(const Info &i) const {
    return (mai != i.mai) ? mai > i.mai : cost < i.cost;
  }
  bool operator==(const Info &i) const {
    return mai == i.mai and cost == i.cost;
  }
  Info operator+(const Info &i) const {
    return Info{mai + i.mai, cost + i.cost};
  }
};
constexpr int MAX = 100;
constexpr int RES = 49900;
constexpr int INF = 1 << 30;
const Info IINF = Info{0, INF};
Info dp[MAX + 100][RES + 100];

int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) {
      break;
    }
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
      cin >> p[i];
    }

    for (int i = 0; i <= MAX; i++) {
      for (int j = 0; j <= RES; j++) {
        dp[i][j] = IINF;
      }
    }
    dp[0][0] = Info{0, 0};

    for (int i = 0; i < n; i++) {
      for (int j = 0; j <= RES; j++) {
        if (not(dp[i][j] == IINF)) {
          const int price = p[i] % 1000;
          dp[i + 1][j] = min(dp[i + 1][j], dp[i][j]);
          int rest = j - price;
          for (int m = 0; m < 2 and m * 500 <= rest; m++) {
            dp[i + 1][rest - m * 500] =
                min(dp[i + 1][rest - m * 500], dp[i][j] + Info{m, p[i]});
          }
          if (price != 0) {
            rest = 1000 + j - price;
            for (int m = 0; m < 2 and m * 500 <= rest; m++) {
              dp[i + 1][rest - m * 500] =
                  min(dp[i + 1][rest - m * 500], dp[i][j] + Info{m, p[i]});
            }
          }
        }
      }
    }

    Info mini = IINF;
    for (int j = 0; j <= RES; j++) {
      mini = min(mini, dp[n][j]);
    }
    cout << mini.mai << " " << mini.cost << endl;
  }
  return 0;
}