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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define PRIME1 99999883
#define PRIME2 99999893
#define EPS 0.00000001
using namespace std;

int D, N;

struct Info {
  Info() {
    attack = exp = r_exp = -1;
    unuse = false;
  }
  Info(int arg_attack, int arg_exp, int arg_r_exp) {
    attack = arg_attack;
    exp = arg_exp;
    r_exp = arg_r_exp;
    unuse = false;
  }
  bool operator<(const struct Info &arg) const { return r_exp > arg.r_exp; };

  int attack, exp, r_exp;
  bool unuse;
};

struct Data {
  int current_exp, rest_D, count;
};

void func() {

  int a, e, r;
  priority_queue<Info> S;

  for (int i = 0; i < N; i++) {
    scanf("%d %d %d", &a, &e, &r);
    S.push(Info(a, e, r));
  }

  Info info[N];

  int index = 0;

  while (!S.empty()) {
    info[index].attack = S.top().attack;
    info[index].exp = S.top().exp;
    info[index].r_exp = S.top().r_exp;
    index++;
    S.pop();
  }

  //??¨????????????????????¨????????????????????????
  int a_num = 0, e_num = 0;
  for (int i = 0; info[i].r_exp == 0 && i < N; i++) {
    if (info[i].attack > 0) {
      a_num++;
    }
    if (info[i].exp > 0) {
      e_num++;
    }
  }

  if (a_num == 0 && e_num == 0) {
    printf("NA\\n");
    return;
  } else {

    if (a_num == 0 &&
        e_num >
            0) { //????¨??????????????????????????????¨??????????????????????????????
      for (int i = 0; i < N; i++) {
        if (info[i].attack > 0)
          a_num++;
      }

      if (a_num == 0) {
        printf("NA\\n");
        return;
      }
    }
  }

  int dp[101][101];

  for (int i = 0; i < 101; i++) {
    for (int k = 0; k < 101; k++)
      dp[i][k] = BIG_NUM;
  }

  dp[D][0] = 0;

  for (int a = 0; a <= 100; a++) {
    for (int b = D; b >= 0; b--) {
      if (dp[b][a] == BIG_NUM)
        continue;
      for (int c = 0; info[c].r_exp <= a && c < N; c++) {
        dp[max(0, b - info[c].attack)][min(100, a + info[c].exp)] =
            min(dp[max(0, b - info[c].attack)][min(100, a + info[c].exp)],
                dp[b][a] + 1);
      }
    }
  }

  int minimum = BIG_NUM;

  for (int i = 0; i < 101; i++) {
    minimum = min(minimum, dp[0][i]);
  }

  if (minimum == BIG_NUM) {
    printf("NA\\n");
  } else {
    printf("%d\\n", minimum);
  }
}

int main() {

  while (true) {
    scanf("%d %d", &D, &N);
    if (D == 0 && N == 0)
      break;

    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define PRIME1 99999883
#define PRIME2 99999893
#define EPS 0.00000001
using namespace std;

int D, N;

struct Info {
  Info() {
    attack = exp = r_exp = -1;
    unuse = false;
  }
  Info(int arg_attack, int arg_exp, int arg_r_exp) {
    attack = arg_attack;
    exp = arg_exp;
    r_exp = arg_r_exp;
    unuse = false;
  }
  bool operator<(const struct Info &arg) const { return r_exp > arg.r_exp; };

  int attack, exp, r_exp;
  bool unuse;
};

struct Data {
  int current_exp, rest_D, count;
};

void func() {

  int a, e, r;
  priority_queue<Info> S;

  for (int i = 0; i < N; i++) {
    scanf("%d %d %d", &a, &e, &r);
    S.push(Info(a, e, r));
  }

  Info info[N];

  int index = 0;

  while (!S.empty()) {
    info[index].attack = S.top().attack;
    info[index].exp = S.top().exp;
    info[index].r_exp = S.top().r_exp;
    index++;
    S.pop();
  }

  //??¨????????????????????¨????????????????????????
  int a_num = 0, e_num = 0;
  for (int i = 0; info[i].r_exp == 0; i++) {
    if (info[i].attack > 0) {
      a_num++;
    }
    if (info[i].exp > 0) {
      e_num++;
    }
  }

  if (a_num == 0 && e_num == 0) {
    printf("NA\\n");
    return;
  } else {

    if (a_num == 0 &&
        e_num >
            0) { //????¨??????????????????????????????¨??????????????????????????????
      for (int i = 0; i < N; i++) {
        if (info[i].attack > 0)
          a_num++;
      }

      if (a_num == 0) {
        printf("NA\\n");
        return;
      }
    }
  }

  int ans = -1;

  queue<Data> Q;

  Data first;
  first.current_exp = 0;
  first.rest_D = D;
  first.count = 0;

  Q.push(first);

  bool FLG;

  while (!Q.empty()) {

    if (Q.front().rest_D <= 0) {
      ans = Q.front().count;
      break;
    }

    //??????????????????????¨?????????????????????????????????????????????¨???????????°???????????¨????????¨????????????
    //????????????????????????0????????°?????¨?????????
    for (int i = 0; info[i].r_exp <= Q.front().current_exp; i++) {
      if ((info[i].unuse == true) || (info[i].attack <= 0 && info[i].exp <= 0))
        continue;
      FLG = true;
      for (int k = 0; k < i; k++) {
        if (info[i].exp <= info[k].exp && info[i].attack <= info[k].attack) {
          FLG = false;
          info[i].unuse = true;
          break;
        }
      }
      if (FLG == true) {
        Data new_data;
        new_data.count = Q.front().count + 1;
        new_data.current_exp = Q.front().current_exp + info[i].exp;
        new_data.rest_D = Q.front().rest_D - info[i].attack;
        Q.push(new_data);
      }
    }
    Q.pop();
  }

  if (ans == -1) {
    printf("NA\\n");
  } else {
    printf("%d\\n", ans);
  }
}

int main() {

  while (true) {
    scanf("%d %d", &D, &N);
    if (D == 0 && N == 0)
      break;

    func();
  }

  return 0;
}