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

#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;

struct mData {
  int typ, index;
  int mh;
};

queue<mData> que;

int route[1010];

char map[110][110];
int LH, H;
int n, m, num, t, p;
int reduce[13];

char str[100];
int dam[26];

short vis[1010][1 << 12];

inline int minnum(const int &x, const int &y) {
  if (x < y)
    return x;
  return y;
}

void dfs(int index, int typ, int mh, int damage, int np) {
  if (np == p) {
    if (mh > damage && vis[mh][typ] < index) {
      mData tem;
      vis[mh][typ] = index;
      tem.index = index;
      tem.mh = mh - damage;
      tem.typ = typ;
      que.push(tem);
    }
    return;
  }
  if (mh <= damage && (typ & (1 << np)) == 0)
    dfs(index, typ + (1 << np), minnum(mh + reduce[np], LH), damage, np + 1);
  dfs(index, typ, mh, damage, np + 1);
}

int main() {
  int i, j, k, ans;
  int x, y;
  mData tem;
  while (scanf("%d%d", &H, &LH) != EOF) {
    if (H == 0 && LH == 0)
      break;
    scanf("%d%d", &n, &m);
    for (i = 0; i < n; i++)
      scanf("%s", map[i]);
    scanf("%d", &i);
    for (; i > 0; i--) {
      scanf("%s%d", str, &j);
      dam[str[0] - 'A'] = j;
    }
    scanf("%d", &t);
    x = 0;
    y = 0;
    num = 0;
    for (i = 0; i < t; i++) {
      scanf("%s%d", str, &j);
      if (str[0] == 'U')
        for (; j > 0; j--) {
          x--;
          route[num++] = dam[map[x][y] - 'A'];
        }
      if (str[0] == 'D')
        for (; j > 0; j--) {
          x++;
          route[num++] = dam[map[x][y] - 'A'];
        }
      if (str[0] == 'L')
        for (; j > 0; j--) {
          y--;
          route[num++] = dam[map[x][y] - 'A'];
        }
      if (str[0] == 'R')
        for (; j > 0; j--) {
          y++;
          route[num++] = dam[map[x][y] - 'A'];
        }
    }
    scanf("%d", &p);
    for (i = 0; i < p; i++)
      scanf("%d", &reduce[i]);
    memset(vis, -1, sizeof(vis));
    while (!que.empty())
      que.pop();
    tem.mh = H;
    tem.typ = 0;
    tem.index = -1;
    if (H > 0)
      que.push(tem);
    for (ans = 0; ans == 0 && !que.empty();) {
      tem = que.front();
      que.pop();
      if (tem.index == num - 1) {
        ans = 1;
        continue;
      }
      dfs(tem.index + 1, tem.typ, tem.mh, route[tem.index + 1], 0);
    }
    if (ans == 1)
      printf("YES\\n");
    else
      printf("NO\\n");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
/*
int st;
        st = 9;
        for (int mask = st ; mask ; mask = st & (mask - 1)) {
                printf("%d\\n",mask);
        }*/
vector<int> son[1 << 12];
int hp, mhp;
int n, m;
char stp[1100][3];
int step[1100];
char mz[110][113];
int dam[110][113];
int dic[444];
int p;
int mp;
int ad[33];
int dp[1100][1 << 12];
int gx[4] = {0, 0, 1, -1};
int gy[4] = {1, -1, 0, 0};
int cnm(char c) {
  if (c == 'U')
    return 3;
  if (c == 'D')
    return 2;
  if (c == 'L')
    return 1;
  if (c == 'R')
    return 0;
  return 0;
}
int bak[11000];
int gao(int c) {
  // if ( c == 0 ) printf("$$$$$$$$$$$$$$$ %d\\n",bak[c]);
  if (bak[c] != -1)
    return bak[c];
  int sum = 0, pc = c;
  for (int i = 0; i < mp; i++) {
    if (c & 1)
      sum += ad[i];
    c >>= 1;
  }
  bak[pc] = sum;
  return sum;
}
int main() {
  for (int st = 0; st < 4096; st++) {
    for (int mask = st; mask; mask = st & (mask - 1)) {
      son[st].push_back(mask);
    }
    son[st].push_back(0);
  }
  while (~scanf("%d%d", &hp, &mhp)) {
    if (hp == 0 && mhp == 0)
      break;
    memset(bak, -1, sizeof(bak));
    cin >> n >> m;
    for (int i = 0; i < n; i++)
      scanf("%s", mz[i]);
    memset(dic, 0, sizeof(dic));
    int tmp;
    cin >> tmp;
    while (tmp--) {
      char ts[10];
      int tx;
      scanf("%s%d", ts, &tx);
      dic[(int)ts[0]] = tx;
    }
    // puts("--");
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        dam[i][j] = dic[(int)mz[i][j]];
      }
    }
    cin >> p;
    for (int i = 0; i < p; i++) {
      scanf("%s%d", stp[i], &step[i]);
    }
    cin >> mp;
    for (int i = 0; i < mp; i++)
      scanf("%d", &ad[i]);
    int bj = (1 << mp) - 1;
    memset(dp, 0, sizeof(dp));
    dp[0][bj] = hp;
    int x = 0, y = 0, sum = 0;
    // printf("***%d\\n",gao(0));
    for (int i = 0; i < p; i++) {
      int dr = cnm(stp[i][0]);

      for (int j = 0; j < step[i]; j++) {
        x += gx[dr], y += gy[dr];
        for (int st = 0; st <= bj; st++) {
          // puts("**");
          if (dp[sum][st] <= 0)
            continue;
          if (gao(st) + dp[sum][st] <= mhp) {
            if (dp[sum][st] + bak[st] > dam[x][y])
              dp[sum + 1][0] =
                  max(dp[sum + 1][0], dp[sum][st] + bak[st] - dam[x][y]);
            continue;
          }
          if (bak[st] + dp[sum][st] <= dam[x][y])
            continue;
          for (int k = 0; k < son[st].size(); k++) {
            int mask = son[st][k];
            int addup = gao(mask);
            int nhp = min(dp[sum][st] + addup, mhp) - dam[x][y];
            if (nhp > 0)
              dp[sum + 1][st ^ mask] = max(dp[sum + 1][st ^ mask], nhp);
          }
        }
        sum++;
      }
    }
    bool fg = false;
    for (int i = 0; i <= bj; i++) {
      if (dp[sum][i] > 0) {
        // printf("$%d\\n", dp[sum][i]);
        fg = true;
        break;
      }
    }
    puts(fg ? "YES" : "NO");
  }
  return 0;
}
/*
1234
*/