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

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { cout << #a << " = " << a << endl; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}

typedef long long ll;
int const inf = 1 << 29;

int N, M;
int HpInit, HpMax;
int H, W;
vector<string> G;
int cost[256];
int portion[12];
int calc_heal[1 << 12];

typedef pair<int, int> pii;
vector<pii> v;

int main() {

  while (cin >> HpInit >> HpMax && (HpInit | HpMax)) {
    cin >> H >> W;
    G.clear();
    G.resize(H);
    rep(i, H) cin >> G[i];
    int Q;
    cin >> Q;
    rep(i, Q) {
      char c;
      cin >> c;
      cin >> cost[(int)c];
    }

    v.clear();
    int y = 0, x = 0;

    cin >> N;
    rep(i, N) {
      char d;
      cin >> d;
      int n;
      cin >> n;
      if (d == 'L') {
        rep(i, n) v.push_back({y, x - i - 1});
        x -= n;
      }
      if (d == 'U') {
        rep(i, n) v.push_back({y - i - 1, x});
        y -= n;
      }
      if (d == 'R') {
        rep(i, n) v.push_back({y, x + i + 1});
        x += n;
      }
      if (d == 'D') {
        rep(i, n) v.push_back({y + i + 1, x});
        y += n;
      }
    }

    cin >> M;
    rep(i, M) cin >> portion[i];

    rep(S, 1 << M) {
      calc_heal[S] = 0;
      rep(i, M) if (S >> i & 1) calc_heal[S] += portion[i];
    }

    static int sum[1010];
    rep(i, 1010) sum[i] = 0;
    rep(i, v.size()) {
      if (i)
        sum[i] += sum[i - 1];
      sum[i] += cost[(int)G[v[i].first][v[i].second]];
    }

    static int dp[1010][1 << 12];
    rep(i, 1010) rep(j, 1 << 12) dp[i][j] = -inf;
    dp[0][0] = HpInit;

    bool ok = 0;

    rep(i, v.size()) {
      const int damage = cost[(int)G[v[i].first][v[i].second]];
      rep(PS, 1 << M) {
        if (dp[i][PS] <= 0)
          continue;
        if (sum[v.size() - 1] - sum[i] + damage < dp[i][PS]) {
          ok = 1;
          goto ex;
        }

        int remain = (1 << M) - 1 - PS;
        for (int b = remain; b >= 0; b--) {
          b &= remain;
          int NPS = PS | ((1 << M) - 1 - PS - b);
          const int heal = calc_heal[NPS ^ PS];
          const int cand = min(HpMax, dp[i][PS] + heal) - damage;
          if (cand > 0)
            maximize(dp[i + 1][NPS], cand);
        }
      }
    }

    rep(i, 1 << M) { ok |= dp[v.size()][i] > 0; }

  ex:;
    cout << (ok ? "YES\\n" : "NO\\n");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { cout << #a << " = " << a << endl; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}

typedef long long ll;
int const inf = 1 << 29;

int N, M;
int HpInit, HpMax;
int H, W;
vector<string> G;
int cost[256];
int portion[12];
int calc_heal[1 << 12];

typedef pair<int, int> pii;
vector<pii> v;

int main() {

  while (cin >> HpInit >> HpMax && (HpInit | HpMax)) {
    cin >> H >> W;
    G.clear();
    G.resize(H);
    rep(i, H) cin >> G[i];
    int Q;
    cin >> Q;
    rep(i, Q) {
      char c;
      cin >> c;
      cin >> cost[(int)c];
    }

    v.clear();
    int y = 0, x = 0;

    cin >> N;
    rep(i, N) {
      char d;
      cin >> d;
      int n;
      cin >> n;
      if (d == 'L') {
        rep(i, n) v.push_back({y, x - i - 1});
        x -= n;
      }
      if (d == 'U') {
        rep(i, n) v.push_back({y - i - 1, x});
        y -= n;
      }
      if (d == 'R') {
        rep(i, n) v.push_back({y, x + i + 1});
        x += n;
      }
      if (d == 'D') {
        rep(i, n) v.push_back({y + i + 1, x});
        y += n;
      }
    }

    cin >> M;
    rep(i, M) cin >> portion[i];

    rep(S, 1 << M) {
      calc_heal[S] = 0;
      rep(i, M) if (S >> i & 1) calc_heal[S] += portion[i];
    }

    static int dp[1010][1 << 12];
    rep(i, 1010) rep(j, 1 << 12) dp[i][j] = -inf;
    dp[0][0] = HpInit;

    rep(i, v.size()) {
      const int damage = cost[(int)G[v[i].first][v[i].second]];
      rep(PS, 1 << M) {
        if (dp[i][PS] <= 0)
          continue;
        int remain = (1 << M) - 1 - PS;
        for (int b = remain; b >= 0; b--) {
          b &= remain;
          int NPS = PS | ((1 << M) - 1 - PS - b);
          const int heal = calc_heal[NPS ^ PS];
          const int cand = min(HpMax, dp[i][PS] + heal) - damage;
          if (cand > 0)
            maximize(dp[i + 1][NPS], cand);
        }
      }
    }

    bool ok = 0;

    rep(i, 1 << M) { ok |= dp[v.size()][i] > 0; }

    cout << (ok ? "YES\\n" : "NO\\n");
  }

  return 0;
}