Problem p03128 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
// #define int long long
#define pb push_back
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
#ifdef ONLINE_JUDGE
#define endl '\n'
#endif
const int mod = (int)1e9 + 7;
const int inf = mod;
using namespace std;
#ifndef ONLINE_JUDGE
#define tr(...)                                                                \
  {                                                                            \
    __l(__LINE__);                                                             \
    __f(#__VA_ARGS__, __VA_ARGS__);                                            \
  }
inline void __l(int line) { cerr << "#" << line << ": "; }
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define tr(...)
#endif
template <class T> void smin(T &a, T val) {
  if (a > val)
    a = val;
}
template <class T> void smax(T &a, T val) {
  if (a < val)
    a = val;
}
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
  bool first = true;
  os << "[";
  for (auto i : v) {
    if (!first)
      os << ", ";
    os << i;
    first = false;
  }
  return os << "]";
}
const int N = (int)1e4 + 10;
// make sure N size is correctttt!!!!!!!!!

int n, a[N], m;
vector<int> f;
int dp[15][N];

int solve(int idx, int coins) {
  if (coins < 0)
    return -inf;

  if (idx == m) {
    return dp[idx][coins] = ((coins == 0) ? 0 : -inf);
  }

  int &ans = dp[idx][coins];
  if (~ans)
    return ans;

  ans = 0;
  if (f[a[idx]] <= coins) {
    smax(ans, 1 + solve(idx, coins - f[a[idx]]));
  }

  smax(ans, solve(idx + 1, coins));
  return ans;
}

void trace(int idx, int coins) {
  if (idx == m) {
    assert(coins == 0);
    exit(0);
  }

  if (f[a[idx]] <= coins) {
    if (solve(idx, coins) == 1 + solve(idx, coins - f[a[idx]])) {
      cout << a[idx];
      return trace(idx, coins - f[a[idx]]);
    }
  }

  return trace(idx + 1, coins);
}

int32_t main() {
  _

          cin >>
      n >> m;
  f = {0, 2, 5, 5, 4, 5, 6, 3, 7, 6};

  memset(dp, -1, sizeof dp);
  for (int i = 0; i < m; ++i)
    cin >> a[i];

  sort(a, a + m);
  reverse(a, a + m);
  int faltu = solve(0, n);
  trace(0, n);

  // make sure N size is correct!!!!!!!!!
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
// #define int long long
#define pb push_back
#define sz(i) (int)(i.size())
#define F first
#define S second
#define L long double
#define P pair<int, int>
#ifdef ONLINE_JUDGE
#define endl '\n'
#endif
const int mod = (int)1e9 + 7;
const int inf = mod;
using namespace std;
#ifndef ONLINE_JUDGE
#define tr(...)                                                                \
  {                                                                            \
    __l(__LINE__);                                                             \
    __f(#__VA_ARGS__, __VA_ARGS__);                                            \
  }
inline void __l(int line) { cerr << "#" << line << ": "; }
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define tr(...)
#endif
template <class T> void smin(T &a, T val) {
  if (a > val)
    a = val;
}
template <class T> void smax(T &a, T val) {
  if (a < val)
    a = val;
}
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
  bool first = true;
  os << "[";
  for (auto i : v) {
    if (!first)
      os << ", ";
    os << i;
    first = false;
  }
  return os << "]";
}
const int N = (int)1e4 + 10;
// make sure N size is correctttt!!!!!!!!!

int n, a[N], m;
vector<int> f;
int dp[15][N];

int solve(int idx, int coins) {
  if (coins < 0)
    return -inf;

  if (idx == m) {
    return dp[idx][coins] = ((coins == 0) ? 0 : -inf);
  }

  int &ans = dp[idx][coins];
  if (~ans)
    return ans;

  ans = -inf;
  if (f[a[idx]] <= coins) {
    smax(ans, 1 + solve(idx, coins - f[a[idx]]));
  }

  smax(ans, solve(idx + 1, coins));
  return ans;
}

void trace(int idx, int coins) {
  if (idx == m) {
    assert(coins == 0);
    exit(0);
  }

  if (f[a[idx]] <= coins) {
    if (solve(idx, coins) == 1 + solve(idx, coins - f[a[idx]])) {
      cout << a[idx];
      return trace(idx, coins - f[a[idx]]);
    }
  }

  return trace(idx + 1, coins);
}

int32_t main() {
  _

          cin >>
      n >> m;
  f = {0, 2, 5, 5, 4, 5, 6, 3, 7, 6};

  memset(dp, -1, sizeof dp);
  for (int i = 0; i < m; ++i)
    cin >> a[i];

  sort(a, a + m);
  reverse(a, a + m);
  int faltu = solve(0, n);
  trace(0, n);

  // make sure N size is correct!!!!!!!!!
  return 0;
}