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

#include <bits/stdc++.h>
using namespace std;
typedef struct magic {
  int mp, damage;
} magic;
int dp_all[2][100000 + 1], dp_single[2][100000 + 1];

int main(int argc, char *argv[]) {
  int n, m;
  while (std::cin >> n, n) {
    int hp[n];
    int max_hp = 0;
    for (int i = 0; i < n; i++) {
      std::cin >> hp[i];
      max_hp = max(max_hp, hp[i]);
    }
    std::cin >> m;
    string s;
    vector<magic> single, all;
    for (int i = 0; i < m; i++) {
      int mp, damage;
      std::cin >> s >> mp >> s >> damage;
      if (damage == 0)
        continue;
      if (s == "All") {
        all.push_back(magic{mp, damage});
      } else {
        single.push_back(magic{mp, damage});
      }
    }
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j <= max_hp; j++) {
        dp_all[i][j] = 1e9;
      }
    }
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j <= max_hp; j++) {
        dp_single[i][j] = 1e9;
      }
    }
    for (int i = 0; i < 2; i++) {
      dp_all[i][0] = 0;
    }
    for (int i = 0; i < 2; i++) {
      dp_single[i][0] = 0;
    }
    for (int i = 0; i < all.size(); i++) {
      int &mp = all[i].mp, &damage = all[i].damage;
      for (int j = 0; j <= max_hp; j++) {
        if (j < damage) {
          dp_all[((i + 1) & 1)][j] = min(mp, dp_all[(i & 1)][j]);
        } else {
          dp_all[((i + 1) & 1)][j] =
              min(dp_all[(i & 1)][j], dp_all[((i + 1) & 1)][j - damage] + mp);
        }
      }
    }
    for (int i = 0; i < single.size(); i++) {
      int &mp = single[i].mp, &damage = single[i].damage;
      for (int j = 0; j <= max_hp; j++) {
        if (j < damage) {
          dp_single[((i + 1) & 1)][j] = min(mp, dp_single[(i & 1)][j]);
        } else {
          dp_single[((i + 1) & 1)][j] = min(
              dp_single[(i & 1)][j], dp_single[(i + 1) & 1][j - damage] + mp);
        }
      }
    }
    long long int ans = 1e10;
    int size_all = all.size(), size_single = single.size();
    for (int i = 0; i <= max_hp; i++) {
      long long int sum = dp_all[size_all & 1][i];
      for (int j = 0; j < n; j++) {
        if (hp[j] - i <= 0)
          continue;
        sum += dp_single[size_single & 1][hp[j] - i];
      }
      ans = min(ans, sum);
    }
    std::cout << ans << std::endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef struct magic {
  int mp, damage;
} magic;
int dp_all[100 + 1][100000 + 1], dp_single[100 + 1][100000 + 1];

int main(int argc, char *argv[]) {
  int n, m;
  while (std::cin >> n, n) {
    vector<int> hp(n);
    int max_hp = 0;
    for (int i = 0; i < n; i++) {
      std::cin >> hp[i];
      max_hp = max(max_hp, hp[i]);
    }
    std::cin >> m;
    string s;
    vector<magic> single, all;
    for (int i = 0; i < m; i++) {
      int mp, damage;
      std::cin >> s >> mp >> s >> damage;
      if (damage == 0)
        continue;
      if (s == "All") {
        all.push_back(magic{mp, damage});
      } else {
        single.push_back(magic{mp, damage});
      }
    }
    for (int i = 0; i <= all.size(); i++) {
      for (int j = 0; j <= max_hp; j++) {
        dp_all[i][j] = 1e9;
      }
    }
    for (int i = 0; i <= single.size(); i++) {
      for (int j = 0; j <= max_hp; j++) {
        dp_single[i][j] = 1e9;
      }
    }
    for (int i = 0; i < all.size(); i++) {
      dp_all[i][0] = 0;
    }
    for (int i = 0; i < single.size(); i++) {
      dp_single[i][0] = 0;
    }
    for (int i = 0; i < all.size(); i++) {
      int &mp = all[i].mp, &damage = all[i].damage;
      for (int j = 0; j <= max_hp; j++) {
        if (j < damage) {
          dp_all[i + 1][j] = min(mp, dp_all[i][j]);
        } else {
          dp_all[i + 1][j] = min(dp_all[i][j], dp_all[i + 1][j - damage] + mp);
        }
      }
    }
    for (int i = 0; i < single.size(); i++) {
      int &mp = single[i].mp, &damage = single[i].damage;
      for (int j = 0; j <= max_hp; j++) {
        if (j < damage) {
          dp_single[i + 1][j] = min(mp, dp_single[i][j]);
        } else {
          dp_single[i + 1][j] =
              min(dp_single[i][j], dp_single[i + 1][j - damage] + mp);
        }
      }
    }
    long long int ans = 1e10;
    int size_all = all.size(), size_single = single.size();
    for (int i = 0; i <= max_hp; i++) {
      long long int sum = dp_all[size_all][i];
      for (int j = 0; j < hp.size(); j++) {
        if (hp[j] - i <= 0)
          continue;
        sum += dp_single[size_single][hp[j] - i];
      }
      ans = min(ans, sum);
    }
    std::cout << ans << std::endl;
  }
  return 0;
}