Problem p02863 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

const int MAX_N = 3000;
const int MAX_T = 3000;

int N, T;
vector<int> As(MAX_N);
vector<int> Bs(MAX_N);

// memo1[i][j] := 0 ~ iでj分以内で食べられる最大値
vector<vector<int>> memo1(MAX_N, vector<int>(MAX_T + 1, -1));
// memo2[i][j] := i ~ T - 1でj分以内で食べられる最大値
vector<vector<int>> memo2(MAX_N, vector<int>(MAX_T + 1, -1));

int dp1(int i, int j) {
  if (memo1[i][j] == -1) {
    if (i == 0) {
      if (j >= As[i]) {
        memo1[i][j] = Bs[i];
      } else {
        memo1[i][j] = 0;
      }
    } else {
      if (j >= As[i]) {
        memo1[i][j] = max(dp1(i - 1, j), dp1(i - 1, j - As[i]) + Bs[i]);
      } else {
        memo1[i][j] = dp1(i - 1, j);
      }
    }
  }
  return memo1[i][j];
}

int dp2(int i, int j) {
  if (memo2[i][j] == -1) {
    if (i == T - 1) {
      if (j >= As[i]) {
        memo2[i][j] = Bs[i];
      } else {
        memo2[i][j] = 0;
      }
    } else {
      if (j >= As[i]) {
        memo2[i][j] = max(dp2(i + 1, j), dp2(i + 1, j - As[i]) + Bs[i]);
      } else {
        memo2[i][j] = dp2(i + 1, j);
      }
    }
  }
  return memo2[i][j];
}

int main() {
  cin >> N >> T;
  for (int i = 0; i < N; i++) {
    cin >> As[i];
    cin >> Bs[i];
  }
  vector<int> ans(N, -1);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < T; j++) {
      if (i == 0) {
        ans[i] = max(ans[i], Bs[i] + dp2(i + 1, T - 1 - j));
      } else if (i == N - 1) {
        ans[i] = max(ans[i], Bs[i] + dp1(i - 1, j));
      } else {
        ans[i] = max(ans[i], Bs[i] + dp1(i - 1, j) + dp2(i + 1, T - 1 - j));
      }
    }
  }
  int r = ans[0];
  for (int i = 0; i < N; i++) {
    r = max(r, ans[i]);
  }
  cout << r << endl;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

const int MAX_N = 3000;
const int MAX_T = 3000;

int N, T;
vector<int> As(MAX_N);
vector<int> Bs(MAX_N);

// memo1[i][j] := 0 ~ iでj分以内で食べられる最大値
vector<vector<int>> memo1(MAX_N, vector<int>(MAX_T + 1, -1));
// memo2[i][j] := i ~ T - 1でj分以内で食べられる最大値
vector<vector<int>> memo2(MAX_N, vector<int>(MAX_T + 1, -1));

int dp1(int i, int j) {
  if (memo1[i][j] == -1) {
    if (i == 0) {
      if (j >= As[i]) {
        memo1[i][j] = Bs[i];
      } else {
        memo1[i][j] = 0;
      }
    } else {
      if (j >= As[i]) {
        memo1[i][j] = max(dp1(i - 1, j), dp1(i - 1, j - As[i]) + Bs[i]);
      } else {
        memo1[i][j] = dp1(i - 1, j);
      }
    }
  }
  return memo1[i][j];
}

int dp2(int i, int j) {
  if (memo2[i][j] == -1) {
    if (i == N - 1) {
      if (j >= As[i]) {
        memo2[i][j] = Bs[i];
      } else {
        memo2[i][j] = 0;
      }
    } else {
      if (j >= As[i]) {
        memo2[i][j] = max(dp2(i + 1, j), dp2(i + 1, j - As[i]) + Bs[i]);
      } else {
        memo2[i][j] = dp2(i + 1, j);
      }
    }
  }
  return memo2[i][j];
}

int main() {
  cin >> N >> T;
  for (int i = 0; i < N; i++) {
    cin >> As[i];
    cin >> Bs[i];
  }
  vector<int> ans(N, -1);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < T; j++) {
      if (i == 0) {
        ans[i] = max(ans[i], Bs[i] + dp2(i + 1, T - 1 - j));
      } else if (i == N - 1) {
        ans[i] = max(ans[i], Bs[i] + dp1(i - 1, j));
      } else {
        ans[i] = max(ans[i], Bs[i] + dp1(i - 1, j) + dp2(i + 1, T - 1 - j));
      }
    }
  }
  int r = ans[0];
  for (int i = 0; i < N; i++) {
    r = max(r, ans[i]);
  }
  cout << r << endl;
}