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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  int row, col;
};

int HP, MAX_HP;
int H, W;
int damage[26], POW[13], portion[12];
int max_HP[1001][4096];
char base_map[100][101], move_route[1000];
Info info[1001];

void func() {

  scanf("%d %d", &H, &W);

  for (int row = 0; row < H; row++) {
    scanf("%s", base_map[row]);
  }

  int T;
  scanf("%d", &T);

  char buf[2];
  int tmp;

  for (int i = 0; i < T; i++) {
    scanf("%s %d", buf, &tmp);
    damage[buf[0] - 'A'] = tmp;
  }

  int S;
  scanf("%d", &S);

  int index = 0;

  for (int i = 0; i < S; i++) {
    scanf("%s %d", buf, &tmp);
    for (int k = 0; k < tmp; k++) {
      move_route[index++] = buf[0];
    }
  }

  S = index;

  info[0].row = 0;
  info[0].col = 0;

  for (int i = 0; i < S; i++) {
    switch (move_route[i]) {
    case 'U':
      info[i + 1].row = info[i].row - 1;
      info[i + 1].col = info[i].col;
      break;
    case 'D':
      info[i + 1].row = info[i].row + 1;
      info[i + 1].col = info[i].col;
      break;
    case 'R':
      info[i + 1].row = info[i].row;
      info[i + 1].col = info[i].col + 1;
      break;
    case 'L':
      info[i + 1].row = info[i].row;
      info[i + 1].col = info[i].col - 1;
      break;
    }
  }

  int P;
  scanf("%d", &P);

  for (int i = 0; i < P; i++) {
    scanf("%d", &portion[i]);
  }

  for (int i = 0; i <= S; i++) {
    for (int state = 0; state < POW[P]; state++)
      max_HP[i][state] = 0;
  }

  max_HP[0][0] = HP;

  int next_damage, next_HP, next_state;

  for (int move = 1; move <= S; move++) {
    next_damage = damage[base_map[info[move].row][info[move].col] - 'A'];
    for (int state = 0; state < POW[P]; state++) {
      if (max_HP[move - 1][state] == 0)
        continue;

      if (max_HP[move - 1][state] > next_damage) {
        max_HP[move][state] =
            max(max_HP[move][state], max_HP[move - 1][state] - next_damage);
      }

      for (int loop = 0; loop < P; loop++) {
        if (state & (1 << loop)) {
          // Do nothing
        } else {
          next_HP = min(MAX_HP, max_HP[move - 1][state] + portion[loop]);
          if (next_HP <= next_damage)
            continue;
          next_state = state + POW[loop];

          max_HP[move][next_state] =
              max(max_HP[move][next_state], next_HP - next_damage);
        }
      }
    }
  }

  for (int state = 0; state < POW[P]; state++) {
    if (max_HP[S][state] > 0) {
      printf("YES\\n");
      return;
    }
  }
  printf("NO\\n");
}

int main() {

  for (int i = 0; i < 13; i++)
    POW[i] = pow(2, i);

  for (int i = 0; i < 26; i++)
    damage[i] = 999;

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

    func();
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  Info(int arg_row, int arg_col, int arg_num, int arg_state, int arg_currentHP,
       int arg_sum_damage) {
    row = arg_row;
    col = arg_col;
    num = arg_num;
    state = arg_state;
    currentHP = arg_currentHP;
    sum_damage = arg_sum_damage;
  }
  int row, col, num, state, currentHP, sum_damage;
};

int HP, MAX_HP;
int H, W;
int damage[26], POW[13], portion[12];
int max_HP[1001][4096];
char base_map[100][101], move_route[1000];

void func() {

  scanf("%d %d", &H, &W);

  for (int row = 0; row < H; row++) {
    scanf("%s", base_map[row]);
  }

  int T;
  scanf("%d", &T);

  char buf[2];
  int tmp;

  for (int i = 0; i < T; i++) {
    scanf("%s %d", buf, &tmp);
    damage[buf[0] - 'A'] = tmp;
  }

  int S;
  scanf("%d", &S);

  int index = 0;

  for (int i = 0; i < S; i++) {
    scanf("%s %d", buf, &tmp);
    for (int k = 0; k < tmp; k++) {
      move_route[index++] = buf[0];
    }
  }

  S = index;

  int P;
  scanf("%d", &P);

  for (int i = 0; i < P; i++) {
    scanf("%d", &portion[i]);
  }

  for (int i = 0; i <= S; i++) {
    for (int k = 0; k < POW[P]; k++)
      max_HP[i][k] = 0;
  }

  queue<Info> Q;
  max_HP[0][0] = HP;
  Q.push(Info(0, 0, 0, 0, HP, 0));

  int next_row, next_col, next_damage, next_HP;
  bool FLG;

  while (!Q.empty()) {

    if (Q.front().num == S) {
      printf("YES\\n");
      return;
    } else if (Q.front().currentHP < max_HP[Q.front().num][Q.front().state]) {
      Q.pop();
    } else {

      switch (move_route[Q.front().num]) {
      case 'U':
        next_row = Q.front().row - 1;
        next_col = Q.front().col;
        break;
      case 'D':
        next_row = Q.front().row + 1;
        next_col = Q.front().col;
        break;
      case 'L':
        next_row = Q.front().row;
        next_col = Q.front().col - 1;
        break;
      case 'R':
        next_row = Q.front().row;
        next_col = Q.front().col + 1;
        break;
      }

      next_damage = damage[base_map[next_row][next_col] - 'A'];

      if (next_damage == 0) {
        if (max_HP[Q.front().num + 1][Q.front().state] < Q.front().currentHP) {
          max_HP[Q.front().num + 1][Q.front().state] = Q.front().currentHP;
          Q.push(Info(next_row, next_col, Q.front().num + 1, Q.front().state,
                      Q.front().currentHP, Q.front().sum_damage));
        }
      } else {

        for (int next_state = Q.front().state; next_state < POW[P];
             next_state++) {

          FLG = true;
          tmp = 0;

          for (int loop = 0; loop < P; loop++) {
            if ((Q.front().state & (1 << loop)) == 0 &&
                (next_state & (1 << loop)) != 0) {
              tmp += portion[loop];
            } else if ((Q.front().state & (1 << loop)) != 0 &&
                       (next_state & (1 << loop)) == 0) {
              FLG = false;
              break;
            }
          }

          if (!FLG)
            continue;

          next_HP = min(MAX_HP, Q.front().currentHP + tmp);

          if (next_HP <= next_damage)
            continue;

          next_HP -= next_damage;

          if (max_HP[Q.front().num + 1][next_state] < next_HP) {
            max_HP[Q.front().num + 1][next_state] = next_HP;
            Q.push(Info(next_row, next_col, Q.front().num + 1, next_state,
                        next_HP, Q.front().sum_damage + next_damage));
          }
        }
      }
      Q.pop();
    }
  }

  printf("NO\\n");
}

int main() {

  for (int i = 0; i < 13; i++)
    POW[i] = pow(2, i);

  for (int i = 0; i < 26; i++)
    damage[i] = 999;

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

    func();
  }

  return 0;
}