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

#include <cstdio>

using namespace std;

void rec(int n, int w, int &v, int &rw, const int W, const int N,
         const int lv[], const int lw[]) {
  v = rw = 0;
  if (n == N) {
    // not remain any treasure
    v = 0;
    rw = w;
  } else if (w < lw[n]) {
    // cannot pack treasure[n]
    rec(n + 1, w, v, rw, W, N, lv, lw);
  } else {
    int v1, v2, w1, w2;

    // through treasure[n]
    rec(n + 1, w, v, rw, W, N, lv, lw);
    v1 = v;
    w1 = rw;
    // pack treasure[n]
    rec(n + 1, w - lw[n], v, rw, W, N, lv, lw);
    v2 = v + lv[n];
    w2 = rw - lw[n];

    // which is good
    if (v1 > v2) {
      v = v1;
      rw = w1;
    } else if (v1 < v2) {
      v = v2;
      rw = w2;
    } else {
      if (w1 >= w2) {
        v = v1;
        rw = w1;
      } else {
        v = v2;
        rw = w2;
      }
    }
  }
  // printf("  (%d, %d, %d, %d) -> (%d, %d)\\n", n, w, v, rw, v, rw);
}

#define SIZE 1001
int dp_v[SIZE][SIZE];
int dp_rw[SIZE][SIZE];

void rec_dp(int n, int w, int &v, int &rw, const int W, const int N,
            const int lv[], const int lw[]) {
  // memo'd
  if (dp_v[n][w] != -1 && dp_rw[n][w] != -1) {
    v = dp_v[n][w];
    rw = dp_rw[n][w];
    return;
  }

  v = rw = 0;
  if (n == N) {
    // not remain any treasure
    v = 0;
    rw = w;
  } else if (w < lw[n]) {
    // cannot pack treasure[n]
    rec_dp(n + 1, w, v, rw, W, N, lv, lw);
  } else {
    int v1, v2, w1, w2;

    // through treasure[n]
    rec_dp(n + 1, w, v, rw, W, N, lv, lw);
    v1 = v;
    w1 = rw;
    // pack treasure[n]
    rec_dp(n + 1, w - lw[n], v, rw, W, N, lv, lw);
    v2 = v + lv[n];
    w2 = rw;

    // which is good
    if (v1 > v2) {
      v = v1;
      rw = w1;
    } else if (v1 < v2) {
      v = v2;
      rw = w2;
    } else {
      if (w1 >= w2) {
        v = v1;
        rw = w1;
      } else {
        v = v2;
        rw = w2;
      }
    }
  }
  // printf("  (%d, %d, %d, %d) -> (%d, %d)\\n", n, w, v, rw, v, rw);
  dp_v[n][w] = v;
  dp_rw[n][w] = rw;
}

int main() {
  for (int icase = 1;; ++icase) {
    int W, N;
    scanf("%d", &W);
    if (W == 0)
      break;
    scanf("%d", &N);

    int v[1000], w[1000];
    for (int i = 0; i < N; ++i)
      scanf("%d,%d", &v[i], &w[i]);

    int retv, retw;
    for (int i = 0; i < SIZE; ++i)
      for (int j = 0; j < SIZE; ++j)
        dp_v[i][j] = dp_rw[i][j] = -1;
    rec_dp(0, W, retv, retw, W, N, v, w);

    printf("Case %d:\\n%d\\n%d\\n", icase, retv, W - retw);
  }

  return 0;
}

Error: 0

Fixed submission:

#include <cstdio>

using namespace std;

void rec(int n, int w, int &v, int &rw, const int W, const int N,
         const int lv[], const int lw[]) {
  v = rw = 0;
  if (n == N) {
    // not remain any treasure
    v = 0;
    rw = w;
  } else if (w < lw[n]) {
    // cannot pack treasure[n]
    rec(n + 1, w, v, rw, W, N, lv, lw);
  } else {
    int v1, v2, w1, w2;

    // through treasure[n]
    rec(n + 1, w, v, rw, W, N, lv, lw);
    v1 = v;
    w1 = rw;
    // pack treasure[n]
    rec(n + 1, w - lw[n], v, rw, W, N, lv, lw);
    v2 = v + lv[n];
    w2 = rw - lw[n];

    // which is good
    if (v1 > v2) {
      v = v1;
      rw = w1;
    } else if (v1 < v2) {
      v = v2;
      rw = w2;
    } else {
      if (w1 >= w2) {
        v = v1;
        rw = w1;
      } else {
        v = v2;
        rw = w2;
      }
    }
  }
  // printf("  (%d, %d, %d, %d) -> (%d, %d)\\n", n, w, v, rw, v, rw);
}

int dp_v[1000][1000];
int dp_rw[1000][1000];

void rec_dp(int n, int w, int &v, int &rw, const int W, const int N,
            const int lv[], const int lw[]) {
  // memo'd
  if (dp_v[n][w] != -1 && dp_rw[n][w] != -1) {
    v = dp_v[n][w];
    rw = dp_rw[n][w];
    return;
  }

  v = rw = 0;
  if (n == N) {
    // not remain any treasure
    v = 0;
    rw = w;
  } else if (w < lw[n]) {
    // cannot pack treasure[n]
    rec_dp(n + 1, w, v, rw, W, N, lv, lw);
  } else {
    int v1, v2, w1, w2;

    // through treasure[n]
    rec_dp(n + 1, w, v, rw, W, N, lv, lw);
    v1 = v;
    w1 = rw;
    // pack treasure[n]
    rec_dp(n + 1, w - lw[n], v, rw, W, N, lv, lw);
    v2 = v + lv[n];
    w2 = rw;

    // which is good
    if (v1 > v2) {
      v = v1;
      rw = w1;
    } else if (v1 < v2) {
      v = v2;
      rw = w2;
    } else {
      if (w1 >= w2) {
        v = v1;
        rw = w1;
      } else {
        v = v2;
        rw = w2;
      }
    }
  }
  // printf("  (%d, %d, %d, %d) -> (%d, %d)\\n", n, w, v, rw, v, rw);
  dp_v[n][w] = v;
  dp_rw[n][w] = rw;
}

int main() {
  for (int icase = 1;; ++icase) {
    int W, N;
    scanf("%d", &W);
    if (W == 0)
      break;
    scanf("%d", &N);

    int v[1000], w[1000];
    for (int i = 0; i < N; ++i)
      scanf("%d,%d", &v[i], &w[i]);

    int retv, retw;
    for (int i = 0; i < 1000; ++i)
      for (int j = 0; j < 1000; ++j)
        dp_v[i][j] = dp_rw[i][j] = -1;
    rec_dp(0, W, retv, retw, W, N, v, w);

    printf("Case %d:\\n%d\\n%d\\n", icase, retv, W - retw);
  }

  return 0;
}