Problem p01088 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, int> T;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); (i)++)
#define repn(i, a, n) for (int(i) = (a); (i) < (int)(n); (i)++)
#define EQ(a, b) (abs((a) - (b)) < eps)
template <class T> void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <class T> void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
int n;
int p[105];
P dp[105][100000];
P dfs(int id, int ch) {
  if (id == n) {
    return P(0, 0);
  }
  int rem = p[id] % 1000;
  if (dp[id][ch].fi != -1)
    return dp[id][ch];
  P res = dfs(id + 1, ch);
  if (rem == 0) {
    if (ch >= 500) {
      P tmp = dfs(id + 1, ch - 500);
      tmp.fi++;
      tmp.sec -= p[id];
      res = max(res, tmp);
    }
  } else {
    if (ch + 500 - rem >= 0) {
      P tmp = dfs(id + 1, ch + 500 - rem);
      tmp.fi++;
      tmp.sec -= p[id];
      res = max(res, tmp);
    }
    P tmp = dfs(id + 1, ch + 1000 - rem);
    tmp.sec -= p[id];
    res = max(res, tmp);
  }
  return dp[id][ch] = res;
}
bool solve() {
  cin >> n;
  if (n == 0)
    return false;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
  }
  for (int i = 0; i < 105; i++) {
    for (int j = 0; j < 100000; j++) {
      dp[i][j] = P(-1, -1);
    }
  }
  P ans = dfs(0, 0);
  cout << ans.fi << ' ' << -ans.sec << endl;
  return true;
}
int main() {
  while (solve()) {
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, int> T;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); (i)++)
#define repn(i, a, n) for (int(i) = (a); (i) < (int)(n); (i)++)
#define EQ(a, b) (abs((a) - (b)) < eps)
template <class T> void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <class T> void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
int n;
int p[105];
int c[5] = {100, 50, 10, 5, 1};
map<vector<int>, P> dp[105];
pair<int, vector<int>> charge(int x) {
  x %= 1000;
  vector<int> v(5, 0);
  int f = x / 500;
  x -= f * 500;
  for (int i = 0; i < 5; i++) {
    v[i] = x / c[i];
    x -= v[i] * c[i];
  }
  assert(x == 0);
  return make_pair(f, v);
}
void dump(vector<int> &v) {
  for (int i = 0; i < v.size(); i++) {
    cout << v[i] << ' ';
  }
  cout << endl;
}
P dfs(int id, vector<int> vec) {
  /*cout << "call : " << id << endl;
  cout << "vec : ";
  dump(vec);
  cout << endl;*/
  vector<int> tmp = vec;
  if (id == n) {
    return P(0, 0);
  }
  map<vector<int>, P>::iterator it;
  it = dp[id].find(vec);
  if (it != dp[id].end()) {
    return (it->sec);
  }
  P res = dfs(id + 1, vec);
  int h = ((p[id] - 1) / 1000 + 1) * 1000;
  ;
  for (int i = 0; i < 5; i++) {
    while (vec[i] > 0 && h - p[id] + c[i] < 1000) {
      vec[i]--;
      h += c[i];
    }
  }
  pair<int, vector<int>> ch = charge(h - p[id]);
  for (int i = 0; i < 5; i++)
    vec[i] += (ch.sec)[i];
  P res2 = dfs(id + 1, vec);
  res2.fi += ch.fi;
  res2.sec -= p[id];
  dp[id][tmp] = max(res, res2);
  /*cout << "end : " << id << endl;
  cout << "vec : ";
  dump();
  cout << "result : " << dp[id][vec].fi << ' ' << -dp[id][vec].sec << endl;*/
  return dp[id][tmp];
}
bool solve() {
  cin >> n;
  if (n == 0)
    return false;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
  }
  for (int i = 0; i < 105; i++)
    dp[i].clear();
  vector<int> v;
  for (int i = 0; i < 5; i++)
    v.pb(0);
  P ans = dfs(0, v);
  cout << ans.fi << ' ' << -ans.sec << endl;
  return true;
}
int main() {
  while (solve()) {
  }
  return 0;
}