Problem p03526 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

struct Box {
  ll str;
  ll w;
};

ll dp[1001][1001];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<Box> v(n + 1);
  for (int i = 1; i <= n; ++i) {
    cin >> v[i].str >> v[i].w;
  }

  sort(v.begin() + 1, v.end(),
       [](const Box &a, const Box &b) { return a.str + a.w < b.str + b.w; });

  for (int i = 0; i < 1001; ++i)
    for (int j = 0; j < 1001; ++j)
      dp[i][j] = -1;

  dp[1][1] = v[1].w;
  for (int pref = 2; pref <= n; ++pref) {
    dp[pref][1] = min(v[pref].w, dp[pref - 1][1]);
  }
  for (int pref = 2; pref <= n; ++pref) {
    if (dp[pref - 1][pref - 1] == -1) {
      dp[pref][pref] = -1;
    } else if (v[pref].str >= dp[pref - 1][pref - 1]) {
      dp[pref][pref] = dp[pref - 1][pref - 1] + v[pref].w;
    } else {
      dp[pref][pref] = -1;
    }
  }

  for (int pref = 3; pref <= n; ++pref) {
    for (int used = 2; used < pref; ++used) {
      if (dp[pref - 1][used] == -1) {
        if (dp[pref - 1][used - 1] == -1) {
          dp[pref][used] = -1;
        } else if (dp[pref - 1][used - 1] <= v[pref].str) {
          dp[pref][used] = v[pref].w + dp[pref - 1][used - 1];
        } else {
          dp[pref][used] = -1;
        }
      } else {
        dp[pref][used] = dp[pref - 1][used];
        if (dp[pref - 1][used - 1] <= v[pref].str) {
          dp[pref][used] =
              min(dp[pref][used], v[pref].w + dp[pref - 1][used - 1]);
        }
      }
    }
  }

  int ans;
  for (int used = n; used >= 1; --used) {
    for (int pref = n; pref >= used; --pref) {
      if (dp[pref][used] != -1) {
        ans = used;
        goto end;
      }
    }
  }
end:
  cout << ans << '\n';
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

struct Box {
  ll str;
  ll w;
};

ll dp[5001][5001];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<Box> v(n + 1);
  for (int i = 1; i <= n; ++i) {
    cin >> v[i].str >> v[i].w;
  }

  sort(v.begin() + 1, v.end(),
       [](const Box &a, const Box &b) { return a.str + a.w < b.str + b.w; });

  for (int i = 0; i < 1001; ++i)
    for (int j = 0; j < 1001; ++j)
      dp[i][j] = -1;

  dp[1][1] = v[1].w;
  for (int pref = 2; pref <= n; ++pref) {
    dp[pref][1] = min(v[pref].w, dp[pref - 1][1]);
  }
  for (int pref = 2; pref <= n; ++pref) {
    if (dp[pref - 1][pref - 1] == -1) {
      dp[pref][pref] = -1;
    } else if (v[pref].str >= dp[pref - 1][pref - 1]) {
      dp[pref][pref] = dp[pref - 1][pref - 1] + v[pref].w;
    } else {
      dp[pref][pref] = -1;
    }
  }

  for (int pref = 3; pref <= n; ++pref) {
    for (int used = 2; used < pref; ++used) {
      if (dp[pref - 1][used] == -1) {
        if (dp[pref - 1][used - 1] == -1) {
          dp[pref][used] = -1;
        } else if (dp[pref - 1][used - 1] <= v[pref].str) {
          dp[pref][used] = v[pref].w + dp[pref - 1][used - 1];
        } else {
          dp[pref][used] = -1;
        }
      } else {
        dp[pref][used] = dp[pref - 1][used];
        if (dp[pref - 1][used - 1] <= v[pref].str) {
          dp[pref][used] =
              min(dp[pref][used], v[pref].w + dp[pref - 1][used - 1]);
        }
      }
    }
  }

  int ans;
  for (int used = n; used >= 1; --used) {
    for (int pref = n; pref >= used; --pref) {
      if (dp[pref][used] != -1) {
        ans = used;
        goto end;
      }
    }
  }
end:
  cout << ans << '\n';
}