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

#include <bits/stdc++.h>

int dp[128][128][1024];
int n;
int P[128];

void init() {
  for (int i = 0; i < 128; ++i) {
    for (int j = 0; j < 128; ++j) {
      for (int k = 0; k < 1024; ++k) {
        dp[i][j][k] = -1;
      }
    }
  }
}

int main() {
  for (;;) {
    init();
    scanf("%d", &n);
    if (n == 0)
      break;
    for (int i = 0; i < n; ++i) {
      scanf("%d", &P[i]);
    }
    dp[0][0][0] = 0;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        for (int k = 0; k < 1024; ++k) {
          if (dp[i][j][k] == -1)
            continue;
          dp[i + 1][j][k] = std::max(dp[i + 1][j][k], dp[i][j][k]);
          // 1000
          int count_1000_2 = (P[i] + 999) / 1000;
          int rem0 = count_1000_2 * 1000 - P[i];
          int &next0 =
              dp[i + 1][j + (rem0 % 1000 >= 500 ? 1 : 0)][k + count_1000_2];
          next0 = std::max(next0, dp[i][j][k] +
                                      (rem0 % 1000 >= 500 ? rem0 - 500 : rem0));
          //
          int count_1000 = (P[i] + 999) / 1000;
          int rem1 = dp[i][j][k] + count_1000 * 1000 - P[i];
          int &next = dp[i + 1][j + (rem1 >= 500 ? 1 : 0)][k + count_1000];
          next = std::max(next, rem1 >= 500 ? rem1 - 500 : rem1);
          // //
          // int rem11 = rem1 % 1000;
          // int& next1 = dp[i+1][j + (rem11%1000>=500 ? 1 : 0)][k +
          // count_1000]; next1 = std::max(next1, rem11%1000>=500 ? rem11 - 500
          // : rem11); rem
          if (dp[i][j][k] > P[i]) {
            int rem2 = dp[i][j][k] - P[i];
            int &next = dp[i + 1][j + (rem2 % 1000 >= 500 ? 1 : 0)][k];
            next = std::max(next, (rem2 % 1000 >= 500 ? rem2 - 500 : rem2));
          }
        }
      }
    }
    for (int i = 0; i < 6; ++i) {
      for (int j = 0; j < 6; ++j) {
        for (int k = 0; k < 6; ++k) {
          // printf("(i, j, k) = (%d, %d, %d) : %d\\n", i, j, k, dp[i][j][k]);
        }
      }
    }
    int res = (1 << 28);
    int max = -1;
    for (int j = n; j >= 0; --j) {
      for (int k = 0; k < 1024; ++k) {
        if (dp[n][j][k] == -1)
          continue;
        int cost = k * 1000 - 500 * j - dp[n][j][k];
        res = std::min(res, cost);
      }
      if (res != (1 << 28)) {
        max = j;
        break;
      }
    }
    printf("%d %d\\n", max, res);
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

int dp[128][128][256];
int n;
int P[64];

void init() {
  for (int i = 0; i < 128; ++i) {
    for (int j = 0; j < 128; ++j) {
      for (int k = 0; k < 256; ++k) {
        dp[i][j][k] = -1;
      }
    }
  }
}

int main() {
  for (;;) {
    init();
    scanf("%d", &n);
    if (n == 0)
      break;
    for (int i = 0; i < n; ++i) {
      scanf("%d", &P[i]);
    }
    dp[0][0][0] = 0;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        for (int k = 0; k < 256; ++k) {
          if (dp[i][j][k] == -1)
            continue;
          dp[i + 1][j][k] = std::max(dp[i + 1][j][k], dp[i][j][k]);
          // 1000
          int count_1000_2 = (P[i] + 999) / 1000;
          int rem0 = count_1000_2 * 1000 - P[i];
          int &next0 =
              dp[i + 1][j + (rem0 % 1000 >= 500 ? 1 : 0)][k + count_1000_2];
          next0 = std::max(next0, dp[i][j][k] +
                                      (rem0 % 1000 >= 500 ? rem0 - 500 : rem0));
          //
          int count_1000 = (P[i] + 999) / 1000;
          int rem1 = dp[i][j][k] + count_1000 * 1000 - P[i];
          int &next =
              dp[i + 1][j + (rem1 % 1000 >= 500 ? 1 : 0)][k + count_1000];
          next = std::max(next, rem1 % 1000 >= 500 ? rem1 - 500 : rem1);
          // rem
          if (dp[i][j][k] > P[i]) {
            int rem2 = dp[i][j][k] - P[i];
            int &next = dp[i + 1][j + (rem2 % 1000 >= 500 ? 1 : 0)][k];
            next = std::max(next, (rem2 % 1000 >= 500 ? rem2 - 500 : rem2));
          }
        }
      }
    }
    // for(int i = 0; i <= 4; ++i) {
    //   for(int j = 0; j <= 4; ++j) {
    //     for(int k = 0; k < 6; ++k) {
    //       printf("(i, j, k) = (%d, %d, %d) : %d\\n", i, j, k, dp[i][j][k]);
    //     }
    //   }
    // }
    int res = (1 << 28);
    int max = -1;
    for (int j = n; j >= 0; --j) {
      for (int k = 0; k < 256; ++k) {
        if (dp[n][j][k] == -1)
          continue;
        int cost = k * 1000 - 500 * j - dp[n][j][k];
        res = std::min(res, cost);
      }
      if (res != (1 << 28)) {
        max = j;
        break;
      }
    }
    printf("%d %d\\n", max, res);
  }

  return 0;
}