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

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

short memo[1001][101][101];

int n, m, x;
int limit;
int secE[110];
int secS[110];
int e[110];
int s[110];
char str[1000];

int calc(int use, int depth, int art) {
  if (use > limit) {
    return -30000;
  }
  if (depth == m) {
    return art >= x ? 0 : -30000;
  }
  if (memo[use][depth][art] != -1) {
    return memo[use][depth][art];
  }
  int ret = -30000;
  ret = max(ret, calc(use, depth + 1, art));
  ret = max(ret, calc(use + e[depth], depth + 1, art + 1) + s[depth]);
  return memo[use][depth][art] = ret;
}

int main() {
  while (scanf("%d %d %d %d", &limit, &n, &m, &x), limit | n | m | x) {
    MEMSET(memo, -1);
    REP(i, n) { scanf("%s %d %d", str, &secE[i], &secS[i]); }
    REP(i, m) { scanf("%s %d %d", str, &e[i], &s[i]); }
    int ans = 0;
    REP(i, n) {
      {
        int use = secE[i];
        int sat = secS[i];
        ans = max(ans, calc(use, 0, 0) + sat);
      }
      REP(j, i) {
        int use = secE[i] + secE[j];
        int sat = secS[i] + secS[j];
        ans = max(ans, calc(use, 0, 0) + sat);
      }
    }
    printf("%d\\n", ans);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int memo[1001][101][101];

int n, m, x;
int limit;
int secE[110];
int secS[110];
int e[110];
int s[110];
char str[1000];

int calc(int use, int depth, int art) {
  if (use > limit) {
    return -100000000;
  }
  if (depth == m) {
    return art >= x ? 0 : -100000000;
  }
  if (memo[use][depth][art] != -1) {
    return memo[use][depth][art];
  }
  int ret = -100000000;
  ret = max(ret, calc(use, depth + 1, art));
  ret = max(ret, calc(use + e[depth], depth + 1, art + 1) + s[depth]);
  return memo[use][depth][art] = ret;
}

int main() {
  while (scanf("%d %d %d %d", &limit, &n, &m, &x), limit | n | m | x) {
    MEMSET(memo, -1);
    REP(i, n) { scanf("%s %d %d", str, &secE[i], &secS[i]); }
    REP(i, m) { scanf("%s %d %d", str, &e[i], &s[i]); }
    int ans = 0;
    REP(i, n) {
      {
        int use = secE[i];
        int sat = secS[i];
        ans = max(ans, calc(use, 0, 0) + sat);
      }
      REP(j, i) {
        int use = secE[i] + secE[j];
        int sat = secS[i] + secS[j];
        ans = max(ans, calc(use, 0, 0) + sat);
      }
    }
    printf("%d\\n", ans);
  }
}