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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 1 << 25;
int cost[11][11][11][11][55]; // depth, pos, l, r, oxy

struct S {
  int depth, pos, l, r, oxy, sum;
  bool operator<(const S &x) const { return sum > x.sum; }
};
void save(S s, int c) { cost[s.depth][s.pos][s.l][s.r][s.oxy] = c; }
int ret(S s) { return cost[s.depth][s.pos][s.l][s.r][s.oxy]; }

int c[10][10];

int main() {
  int W, H, f, M, O;
  while (cin >> W >> H, W + H) {
    cin >> f >> M >> O;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> c[i][j];
      }
    }

    if (O <= 1) {
      cout << "NA" << endl;
      continue;
    }

    priority_queue<S> q;
    fill((int *)begin(cost), (int *)end(cost), INF);
    for (int j = 0; j < W; j++) {
      S ns = {0, j, j, j, O - 1, 0};
      if (c[0][j] < 0)
        ns.sum = -c[0][j];
      else
        ns.oxy = min(ns.oxy + c[0][j], M);
      save(ns, ns.sum);
      q.push(ns);
    }

    int ans = INF;
    while (q.size()) {
      S s = q.top();
      q.pop();
      if (s.depth == H - 1) {
        ans = min(ans, s.sum);
        break;
      }
      if (ret(s) < s.sum || s.oxy <= 1)
        continue;

      for (int i = 0; i < 3; i++) {
        S ns = {s.depth, s.pos, s.pos, s.pos, s.oxy - 1, s.sum};

        if (i == 0) {
          ns.depth++;
          ns.l = ns.r = ns.pos;
        }
        if (i == 1 && s.pos != 0) {
          ns.pos--;
          if (s.pos == s.l)
            ns.l--;
        }
        if (i == 2 && s.pos != W - 1) {
          ns.pos++;
          if (s.pos == s.r)
            ns.r++;
        }

        int x = c[ns.depth][ns.pos];
        if (x < 0)
          ns.sum -= x;
        else
          ns.oxy = min(ns.oxy + x, M);

        if (ret(ns) > ns.sum) {
          save(ns, ns.sum);
          q.push(ns);
        }
      }
      //// down
      //{
      //	S ns = { s.depth + 1, s.pos, s.pos, s.pos, s.oxy - 1, s.sum };
      //	int x = c[ns.depth][ns.pos];
      //	if(x < 0) ns.sum -= x;
      //	else ns.oxy = min(ns.oxy + x, M);
      //	if(ret(ns) > ns.sum) {
      //		save(ns, ns.sum);
      //		q.push(ns);
      //	}
      //}
      //// left
      // if(s.pos != 0) {
      //	S ns = { s.depth, s.pos - 1, s.pos, s.pos, s.oxy - 1, s.sum };
      //	if(s.pos == s.l) {
      //		ns.l--;
      //		int x = c[ns.depth][ns.pos];
      //		if(x < 0) ns.sum -= x;
      //		else ns.oxy = min(ns.oxy + x, M);
      //	}
      //	if(ret(ns) > ns.sum) {
      //		save(ns, ns.sum);
      //		q.push(ns);
      //	}
      // }
      //// right
      // if(s.pos != W - 1) {
      //	S ns = { s.depth, s.pos + 1, s.pos, s.pos, s.oxy - 1, s.sum };
      //	if(s.pos == s.r) {
      //		ns.r++;
      //		int x = c[ns.depth][ns.pos];
      //		if(x < 0) ns.sum -= x;
      //		else ns.oxy = min(ns.oxy + x, M);
      //	}
      //	if(ret(ns) > ns.sum) {
      //		save(ns, ns.sum);
      //		q.push(ns);
      //	}
      // }
    }

    if (ans > f) {
      cout << "NA" << endl;
    } else {
      cout << ans << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;

const int INF = 1 << 30;
int dp[10][10][1 << 10][51];
bool check[10][10][1 << 10][51];
int field[10][10];
int oxygen[10][10];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int W, H;
  while (cin >> W >> H, W) {
    int f, mo, io;
    cin >> f >> mo >> io;

    for (int y = 0; y < H; y++) {
      for (int x = 0; x < W; x++) {
        int a;
        cin >> a;
        if (a > 0) {
          field[y][x] = 0;
          oxygen[y][x] = a;
        } else {
          field[y][x] = -a;
          oxygen[y][x] = 0;
        }
      }
    }

    fill_n((bool *)check, 10 * 10 * (1 << 10) * 51, false);
    fill_n((int *)dp, 10 * 10 * (1 << 10) * 51, INF);
    for (int x = 0; x < W; x++) {
      if (field[0][x]) {
        dp[0][x][1 << x][io - 1] = field[0][x];
      } else {
        dp[0][x][1 << x][min(io - 1 + oxygen[0][x], mo)] = 0;
      }
    }

    while (true) {
      int nx = -1, ny = -1, nv = -1, no = -1;
      for (int y = 0; y < H - 1; y++) {
        for (int x = 0; x < W; x++) {
          for (int v = 0; v < (1 << W); v++) {
            for (int o = 2; o <= mo; o++) {
              if (dp[y][x][v][o] == INF)
                continue;
              if (!check[y][x][v][o] &&
                  (nx == -1 || dp[y][x][v][o] < dp[ny][nx][nv][no])) {
                nx = x, ny = y, nv = v, no = o;
              }
            }
          }
        }
      }

      if (nx == -1)
        break;
      check[ny][nx][nv][no] = true;

      for (int dx = -1; dx <= 1; dx += 2) { // ???????§????
        int nnx = nx + dx;
        if (nnx < 0 || W <= nnx)
          continue;
        if (nv & (1 << nnx)) { // ?¨????????????¨?????????
          dp[ny][nnx][nv][no - 1] =
              min(dp[ny][nnx][nv][no - 1], dp[ny][nx][nv][no]);
        } else { // ?¨????????????¨?????????
          int nnv = nv | (1 << nnx);
          int nno = min(no - 1 + oxygen[ny][nnx], mo);
          dp[ny][nnx][nnv][nno] =
              min(dp[ny][nnx][nnv][nno], dp[ny][nx][nv][no] + field[ny][nnx]);
        }
      }
      // ????§????
      int nnv = 1 << nx;
      int nno = min(no - 1 + oxygen[ny + 1][nx], mo);
      dp[ny + 1][nx][nnv][nno] =
          min(dp[ny + 1][nx][nnv][nno], dp[ny][nx][nv][no] + field[ny + 1][nx]);
    }

    int ans = INF;
    for (int x = 0; x < W; x++) {
      for (int v = 0; v < (1 << W); v++) {
        for (int o = 1; o <= mo; o++) {
          ans = min(ans, dp[H - 1][x][v][o]);
        }
      }
    }

    if (f < ans) {
      cout << "NA" << endl;
    } else {
      cout << ans << endl;
    }
  }
}