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

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb(e) push_back(e)
#define fr first
#define sc second

typedef long long ll;
const ll INF = 100000000;
ll dx[4] = {1, 0, -1, 0};
ll dy[4] = {0, 1, 0, -1};
using namespace std;

struct Spell {
  ll mp, target, damage;
  Spell(ll mp = 0, ll target = 0, ll damage = 0)
      : mp(mp), target(target), damage(damage) {}
};

struct State {
  ll cost;
  vector<int> HP;
  State(ll cost = 0, const vector<int> &HP = vector<int>())
      : cost(cost), HP(HP) {}
  bool operator<(const State &rhs) const { return cost > rhs.cost; }
};

ll N;
vector<int> HP;
ll M;
Spell spells[102];
ll dp1[1000006], dp2[1000006];

ll solve() {
  ll ret = INF;
  rep(i, 1000006) dp1[i] = dp2[i] = INF;
  dp1[0] = dp2[0] = 0;
  rep(i, M) rep(j, 1000006) {
    if (j + spells[i].damage >= 1000006)
      continue;
    if (spells[i].target == 0) {
      dp1[j + spells[i].damage] =
          min(dp1[j + spells[i].damage], dp1[j] + spells[i].mp);
    } else {
      dp2[j + spells[i].damage] =
          min(dp2[j + spells[i].damage], dp2[j] + spells[i].mp);
    }
  }
  for (ll i = 1000005; i >= 1; i--) {
    dp2[i - 1] = min(dp2[i], dp2[i - 1]);
    dp1[i - 1] = min(dp1[i], dp1[i - 1]);
  }

  rep(i, 1000006) {
    ll s = dp2[i];
    rep(j, N) { s += dp1[max(0, HP[j] - i)]; }

    // printf("%d %d\\n",i,s);
    ret = min(ret, s);
  }

  return ret;
}

int main() {
  while (cin >> N) {
    HP.clear();
    if (!N)
      break;
    HP.resize(N);
    rep(i, N) cin >> HP[i];
    cin >> M;
    rep(i, M) {
      string s1, s2;
      ll mp, damage;
      cin >> s1 >> mp >> s2 >> damage;
      ll t = 0;
      if (s2 == "All")
        t = 1;
      spells[i] = Spell(mp, t, damage);
    }
    cout << solve() << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb(e) push_back(e)
#define fr first
#define sc second

const int INF = 100000000;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
using namespace std;
typedef pair<int, int> P;
typedef long long ll;

struct Spell {
  int mp, target, damage;
  Spell(int mp = 0, int target = 0, int damage = 0)
      : mp(mp), target(target), damage(damage) {}
};

struct State {
  ll cost;
  vector<int> HP;
  State(int cost = 0, const vector<int> &HP = vector<int>())
      : cost(cost), HP(HP) {}
  bool operator<(const State &rhs) const { return cost > rhs.cost; }
};

int N;
vector<int> HP;
int M;
Spell spells[102];
ll dijk() {
  map<vector<int>, ll> d;
  priority_queue<State> que;
  que.push(State(0, HP));
  d[HP] = 0;
  ll ans = 1e18;
  while (que.size()) {
    State s = que.top();
    que.pop();
    if (s.HP.size() == 0) {
      ans = min(ans, s.cost);
      break;
    }
    // cout<<s.cost<<", "<<s.HP.size()<<endl;
    // if(d.count(s)) continue;

    rep(i, M) {
      vector<int> vec = s.HP;

      if (spells[i].target == 0) {
        vec[0] -= spells[i].damage;
      } else {
        rep(j, vec.size()) vec[j] -= spells[i].damage;
      }
      auto it = vec.begin();
      while (it != vec.end()) {
        if (*it <= 0)
          it = vec.erase(it);
        else
          ++it;
      }

      State next(s.cost + spells[i].mp, vec);
      if (!d.count(vec) || d[vec] > d[s.HP] + spells[i].mp) {
        d[vec] = d[s.HP] + spells[i].mp;
        que.push(next);
      }
    }
  }

  return ans;
}
int main() {
  while (cin >> N) {
    HP.clear();
    if (!N)
      break;
    HP.resize(N);
    rep(i, N) cin >> HP[i];
    cin >> M;
    rep(i, M) {
      string s1, s2;
      int mp, damage;
      cin >> s1 >> mp >> s2 >> damage;
      int t = 0;
      if (s2 == "All")
        t = 1;
      spells[i] = Spell(mp, t, damage);
    }
    cout << dijk() << endl;
  }
  return 0;
}