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

#include <iostream>
#include <map>
#include <queue>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;

int main() {
  int n;
  map<string, int> type;

  type["All"] = 0;
  type["Single"] = 1;

  while (cin >> n && n) {
    vector<int> hp(n);
    vector<pair<int, int>> magic[2];

    REP(i, n) cin >> hp[i];

    int m;
    cin >> m;

    REP(i, m) {
      string name, target;
      int mp, damage;
      cin >> name >> mp >> target >> damage;
      magic[type[target]].push_back(make_pair(mp, damage));
    }

    vector<int> dp[2];
    const int MAX = 1000000 + 1;
    const int inf = 1000000000;

    REP(cc, 2) {
      vector<int> &memo = dp[cc];
      memo = vector<int>(MAX, inf);
      memo[0] = 0;

      REP(i, magic[cc].size()) {
        const int mp = magic[cc][i].first;
        const int damage = magic[cc][i].second;
        REP(j, MAX) if (memo[j] != inf) {
          if (j + damage < MAX)
            memo[j + damage] = min(memo[j + damage], memo[j] + mp);
        }
      }

      // REP(i,MAX) if(memo[i] != inf)
      // cout << i << ": " << memo[i] << endl;

      for (int j = MAX - 1; j > 0; j--) {
        memo[j - 1] = min(memo[j - 1], memo[j]);
      }
    }

    int ans = inf;
    REP(all, MAX) if (dp[0][all] != inf) {
      int mp = dp[0][all];
      if (mp >= ans)
        goto next;
      REP(i, n) {
        if (hp[i] > all) {
          mp += dp[1][hp[i] - all];
          if (mp >= ans)
            goto next;
        }
      }
      ans = mp;
    next:;
    }

    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <map>
#include <queue>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;

int main() {
  int n;
  map<string, int> type;

  type["All"] = 0;
  type["Single"] = 1;

  while (cin >> n, n) {
    vector<int> hp(n);
    vector<pair<int, int>> magic[2];

    REP(i, n) cin >> hp[i];

    int m;
    cin >> m;

    REP(i, m) {
      string name, target;
      int mp, damage;
      cin >> name >> mp >> target >> damage;
      magic[type[target]].push_back(make_pair(mp, damage));
    }

    vector<int> dp[2];
    const int MAX = 100000 + 1;
    const int inf = 100000000;

    REP(cc, 2) {
      vector<int> &memo = dp[cc];
      memo = vector<int>(MAX, inf);
      memo[0] = 0;

      REP(i, magic[cc].size()) {
        const int mp = magic[cc][i].first;
        const int damage = magic[cc][i].second;
        REP(j, MAX) if (memo[j] != inf) {
          for (int k = 1; j + k * damage < MAX; k++) {
            memo[j + k * damage] = min(memo[j + k * damage], memo[j] + k * mp);
          }
        }
      }

      // REP(i,MAX) if(memo[i] != inf)
      // cout << i << ": " << memo[i] << endl;

      if (cc == 1) {
        for (int j = MAX - 1; j > 0; j--) {
          memo[j - 1] = min(memo[j - 1], memo[j]);
        }
      }
    }

    int ans = inf;
    REP(all, MAX) if (dp[0][all] != inf) {
      int mp = dp[0][all];
      if (mp >= ans)
        goto next;
      REP(i, n) {
        if (hp[i] > all) {
          mp += dp[1][hp[i] - all];
          if (mp >= ans)
            goto next;
        }
      }
      ans = mp;
    next:;
    }

    cout << ans << endl;
  }
  return 0;
}