Problem p03734 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#define int long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a) + (size))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
using namespace std;

int N, W;
int w0;
int w[100];
int v[100];
int dp[100 + 1][300 + 1][100 + 1];
int ERROR = -1000000000000;
int INIT = -10000000000000000;

int func(
    int i, int j,
    int k) // i番目までのものを使って強度の総和がj以下となるように選ぶ、ただし全部でk個使う
{
  if (k < 0) {
    return ERROR;
  }
  if (i < 0 && k > 0) {
    return ERROR;
  }
  if (i < 0) {
    return 0;
  }
  if (j < 0) {
    return ERROR;
  }
  if (dp[i][j][k] > INIT) {
    return dp[i][j][k];
  }
  if (j < w[i]) {
    return func(i - 1, j, k);
  }

  int a = func(i - 1, j, k);
  int b = func(i - 1, j - w[i], k - 1) + v[i];
  int res = MAX(a, b);
  dp[i][j][k] = res;
  return res;
}

signed main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++) {
    cin >> w[i] >> v[i];
  }

  for (int i = 0; i < 101; i++) {
    for (int j = 0; j < 301; j++) {
      for (int k = 0; k < 101; k++) {
        dp[i][j][k] = INIT;
      }
    }
  }

  w0 = w[0];

  for (int i = 0; i < N; i++) {
    w[i] -= w0;
  }

  int ans = 0;
  for (int i = 0; i <= N; i++) {
    ans = MAX(ans, func(N - 1, W - i * w0, i));
  }
  cout << ans << endl;
}


Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#define int long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a) + (size))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
using namespace std;

int N, W;
int w0;
int w[100];
int v[100];
int dp[100 + 1][300 + 1][100 + 1];
int ERROR = -1000000000000;
int INIT = -10000000000000000;

int func(
    int i, int j,
    int k) // i番目までのものを使って強度の総和がj以下となるように選ぶ、ただし全部でk個使う
{
  if (k < 0) {
    return ERROR;
  }
  if (i < 0 && k > 0) {
    return ERROR;
  }
  if (i < 0) {
    return 0;
  }
  if (j < 0) {
    return ERROR;
  }
  if (dp[i][j][k] > INIT) {
    return dp[i][j][k];
  }
  if (j < w[i]) {
    return func(i - 1, j, k);
  }

  int a = func(i - 1, j, k);
  int b = func(i - 1, j - w[i], k - 1) + v[i];
  int res = MAX(a, b);
  dp[i][j][k] = res;
  return res;
}

signed main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++) {
    cin >> w[i] >> v[i];
  }

  for (int i = 0; i < 101; i++) {
    for (int j = 0; j < 301; j++) {
      for (int k = 0; k < 101; k++) {
        dp[i][j][k] = INIT;
      }
    }
  }

  w0 = w[0];

  for (int i = 0; i < N; i++) {
    w[i] -= w0;
  }

  int ans = 0;
  for (int i = 0; i <= N; i++) {
    ans = MAX(ans, func(N - 1, MIN(3 * N, W - i * w0), i));
  }
  cout << ans << endl;
}