Problem p03008 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag,
         tree_order_statistics_node_update>; /// find_by_order(),order_of_key()
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  os << '{' << a.f << ", " << a.s << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '{';
  for (int i = 0; i < sz(a); i++) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << a[i];
  }
  os << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const multiset<T> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}
template <class T1, class T2>
ostream &operator<<(ostream &os, const map<T1, T2> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}

vector<pair<int, int>> AB, BA;
int dp1[3][5001];
vector<vector<ll>> dp2;
int calc1(int tr, int money) {
  if (tr == AB.size())
    return money;
  if (dp1[tr][money] != -1)
    return dp1[tr][money];
  int m = money;
  int profit = 0;
  dp1[tr][money] = calc1(tr + 1, m);
  while (m >= AB[tr].s) {
    m -= AB[tr].s;
    profit += AB[tr].f;
    dp1[tr][money] = max(dp1[tr][money], profit + calc1(tr + 1, m));
  }
  return dp1[tr][money];
}
ll calc2(int tr, int money) {
  if (tr == BA.size())
    return money;
  if (dp2[tr][money] != -1)
    return dp2[tr][money];
  int m = money;
  ll profit = 0;
  dp2[tr][money] = calc2(tr + 1, m);
  while (m >= BA[tr].s) {
    m -= BA[tr].s;
    profit += BA[tr].f;
    dp2[tr][money] = max(dp2[tr][money], profit + calc2(tr + 1, m));
  }
  return dp2[tr][money];
}
int main() {
  memset(dp1, -1, sizeof(dp1));
  int n;
  scanf("%i", &n);
  int ga, sa, ba, gb, sb, bb;
  scanf("%i %i %i %i %i %i", &ga, &sa, &ba, &gb, &sb, &bb);
  if (ga > gb)
    BA.pb({ga, gb});
  if (ga < gb)
    AB.pb({gb, ga});
  if (sa > sb)
    BA.pb({sa, sb});
  if (sa < sb)
    AB.pb({sb, sa});
  if (ba > bb)
    BA.pb({ba, bb});
  if (ba < bb)
    AB.pb({bb, ba});
  int novo = calc1(0, n);
  dp2.resize((int)BA.size(), vector<ll>(novo + 1, -1));
  printf("%lld\n", calc2(0, novo));
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag,
         tree_order_statistics_node_update>; /// find_by_order(),order_of_key()
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  os << '{' << a.f << ", " << a.s << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '{';
  for (int i = 0; i < sz(a); i++) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << a[i];
  }
  os << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}
template <class T> ostream &operator<<(ostream &os, const multiset<T> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}
template <class T1, class T2>
ostream &operator<<(ostream &os, const map<T1, T2> &a) {
  os << '{';
  int i = 0;
  for (auto p : a) {
    if (i > 0 && i < sz(a))
      os << ", ";
    os << p;
    i++;
  }
  os << '}';
  return os;
}

vector<pair<int, int>> AB, BA;
int dp1[3][5001];
vector<vector<ll>> dp2;
int calc1(int tr, int money) {
  if (tr == AB.size())
    return money;
  if (dp1[tr][money] != -1)
    return dp1[tr][money];
  int m = money;
  int profit = 0;
  dp1[tr][money] = calc1(tr + 1, m);
  while (m >= AB[tr].s) {
    m -= AB[tr].s;
    profit += AB[tr].f;
    dp1[tr][money] = max(dp1[tr][money], profit + calc1(tr + 1, m));
  }
  return dp1[tr][money];
}
ll calc2(int tr, int money) {
  if (tr == BA.size())
    return money;
  if (dp2[tr][money] != -1)
    return dp2[tr][money];
  int m = money;
  ll profit = 0;
  if (tr == BA.size() - 1) {
    int puta = m / BA[tr].s;
    dp2[tr][money] = (ll)puta * BA[tr].f + m - BA[tr].s * puta;
    return dp2[tr][money];
  }
  dp2[tr][money] = calc2(tr + 1, m);
  while (m >= BA[tr].s) {
    m -= BA[tr].s;
    profit += BA[tr].f;
    dp2[tr][money] = max(dp2[tr][money], profit + calc2(tr + 1, m));
  }
  return dp2[tr][money];
}
int main() {
  memset(dp1, -1, sizeof(dp1));
  int n;
  scanf("%i", &n);
  int ga, sa, ba, gb, sb, bb;
  scanf("%i %i %i %i %i %i", &ga, &sa, &ba, &gb, &sb, &bb);
  if (ga > gb)
    BA.pb({ga, gb});
  if (ga < gb)
    AB.pb({gb, ga});
  if (sa > sb)
    BA.pb({sa, sb});
  if (sa < sb)
    AB.pb({sb, sa});
  if (ba > bb)
    BA.pb({ba, bb});
  if (ba < bb)
    AB.pb({bb, ba});
  int novo = calc1(0, n);
  dp2.resize((int)BA.size(), vector<ll>(novo + 1, -1));
  printf("%lld\n", calc2(0, novo));
  return 0;
}