Problem p01629 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX 100
using namespace std;
typedef long long ll;

/*
dp[day][hotel][number] := minimum
 */
int dp[MAX][MAX][MAX];
int path[MAX][MAX][MAX];
int N, D, p[MAX][MAX];
int debug[MAX];

int main() {
  scanf("%d %d", &N, &D);
  rep(i, MAX) debug[i] = inf;
  rep(i, N) {
    rep(j, D) {
      scanf("%d", &p[i][j]);
      debug[j] = min(debug[j], p[i][j]);
    }
    reverse(p[i], p[i] + D);
  }

  rep(i, MAX) rep(j, MAX) rep(k, MAX) {
    dp[i][j][k] = inf;
    path[i][j][k] = inf;
  }

  rep(i, N) dp[0][i][0] = 0;

  rep(day, D) {
    rep(hotel, N) {
      rep(number, 55) {
        if (dp[day][hotel][number] == inf)
          continue;
        rep(next_hotel, N) {
          int add = (hotel != next_hotel);
          if (dp[day + 1][next_hotel][number + add] >
              dp[day][hotel][number] + p[next_hotel][day]) {
            dp[day + 1][next_hotel][number + add] =
                dp[day][hotel][number] + p[next_hotel][day];
            path[day + 1][next_hotel][number + add] = hotel;
          } else if (dp[day + 1][next_hotel][number + add] ==
                     dp[day][hotel][number] + p[next_hotel][day]) {
            if (path[day + 1][next_hotel][number + add] > hotel)
              path[day + 1][next_hotel][number + add] = hotel;
          }
        }
      }
    }
  }

  int mincost, minnumber, minN;
  mincost = minnumber = minN = inf;

  int debug_i = 0;
  rep(i, D) debug_i += debug[i];

  rep(i, N) rep(j, 55) {
    if (mincost >= dp[D][i][j]) {
      if (mincost == dp[D][i][j]) {
        // cout << "in( mincost : " << mincost << ", minnumber : " << minnumber
        // << ", minN " << minN << ") dp[" << D << "]["<< i << "][" << j << "] =
        // " << dp[D][i][j] << endl;
        if (minnumber >= j) {
          if (minnumber == j) {
            if (minN > i)
              minN = i;
          } else {
            minnumber = j;
            minN = i;
          }
        }
        // cout << "out( mincost : " << mincost << ", minnumber : " << minnumber
        // << ", minN " << minN << ")" << endl;
      } else {
        mincost = dp[D][i][j];
        minnumber = j;
        minN = i;
        // cout << "( mincost : " << mincost << ", minnumber : " << minnumber <<
        // ", minN " << minN << ")" << endl;
      }
    }
  }

  // cout << "!!!( mincost : " << mincost << ", minnumber : " << minnumber << ",
  // minN " << minN << ")" << endl;
  assert(mincost != inf);
  assert(minnumber != inf);
  cout << mincost << " " << minnumber << endl;
  vector<int> ph;
  int d, h, n;

  d = D, h = minN, n = minnumber;

  int diff = p[h][D - 1];
  for (; d >= 0 && n >= 0;) {
    ph.push_back(h);

    int next_h = path[d][h][n];
    int next_n = n - (next_h != h);
    h = next_h;
    n = next_n;
    d--;
    diff += p[h][d - 1];
    if (path[d][h][n] == inf)
      break;
  }
  // assert(diff >= mincost);
  // assert(diff == mincost);
  // reverse(ph.begin(),ph.end());
  assert(ph.size() == D);
  rep(i, ph.size()) {
    cout << ph[i] + 1 << endl;
    assert(ph[i] != inf);
  }
  // assert(debug_i == mincost);

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX 100
using namespace std;
typedef long long ll;

/*
dp[day][hotel][number] := minimum
 */
int dp[MAX][MAX][MAX];
int path[MAX][MAX][MAX];
int N, D, p[MAX][MAX];
int debug[MAX];

int main() {
  scanf("%d %d", &N, &D);
  rep(i, MAX) debug[i] = inf;
  rep(i, N) {
    rep(j, D) {
      scanf("%d", &p[i][j]);
      debug[j] = min(debug[j], p[i][j]);
    }
    reverse(p[i], p[i] + D);
  }

  rep(i, MAX) rep(j, MAX) rep(k, MAX) {
    dp[i][j][k] = inf;
    path[i][j][k] = inf;
  }

  rep(i, N) dp[0][i][0] = 0;

  rep(day, D) {
    rep(hotel, N) {
      rep(number, 55) {
        if (dp[day][hotel][number] == inf)
          continue;
        rep(next_hotel, N) {
          int add = (hotel != next_hotel);
          if (dp[day + 1][next_hotel][number + add] >
              dp[day][hotel][number] + p[next_hotel][day]) {
            dp[day + 1][next_hotel][number + add] =
                dp[day][hotel][number] + p[next_hotel][day];
            path[day + 1][next_hotel][number + add] = hotel;
          } else if (dp[day + 1][next_hotel][number + add] ==
                     dp[day][hotel][number] + p[next_hotel][day]) {
            if (path[day + 1][next_hotel][number + add] > hotel)
              path[day + 1][next_hotel][number + add] = hotel;
          }
        }
      }
    }
  }

  int mincost, minnumber, minN;
  mincost = minnumber = minN = inf;

  int debug_i = 0;
  rep(i, D) debug_i += debug[i];

  rep(i, N) rep(j, 55) {
    if (mincost >= dp[D][i][j]) {
      if (mincost == dp[D][i][j]) {
        if (minnumber >= j) {
          if (minnumber == j) {
            if (minN > i)
              minN = i;
          }
          minnumber = j;
        }
      } else {
        mincost = dp[D][i][j];
        minnumber = j;
        minN = i;
      }
    }
  }
  assert(mincost != inf);
  assert(minnumber != inf);
  cout << mincost << " " << minnumber << endl;
  vector<int> ph;
  int d, h, n;

  d = D, h = minN, n = minnumber;
  int diff = p[h][D - 1];
  for (; d >= 0 && n >= 0;) {
    ph.push_back(h);

    int next_h = path[d][h][n];
    int next_n = n - (next_h != h);
    h = next_h;
    n = next_n;
    d--;
    diff += p[h][d - 1];
    if (path[d][h][n] == inf)
      break;
  }
  // assert(diff >= mincost);
  assert(diff == mincost);
  // reverse(ph.begin(),ph.end());
  assert(ph.size() == D);
  rep(i, ph.size()) {
    cout << ph[i] + 1 << endl;
    assert(ph[i] != inf);
  }
  // assert(debug_i == mincost);

  return 0;
}