Problem p00547 (C++) — buggy submission, verdict: Memory Limit Exceeded

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

struct Point {
  int y, x, i;
};

const int INF = 1e9;
const int NIL = -1;
const int BIT = 1 << 5;
const vector<pair<int, int>> EAST = {{1, 0}, {3, 2}, {5, 3}, {6, 4}};
const vector<pair<int, int>> SOUTH = {{3, 0}, {5, 1}, {4, 2}, {6, 3}};

int H, W;
vector<vector<int>> S;

vector<Point> neighbor(int y, int x) {
  //   return {{y-1, x, 0}, {y, x-1, 2}, {y, x+1, 5}, {y+1, x, 6}};
  vector<Point> res;
  res.push_back({y - 1, x, 0});
  res.push_back({y, x - 1, 2});
  res.push_back({y, x + 1, 5});
  res.push_back({y + 1, x, 6});
  return res;
}
auto valid(int y, int x) { return 0 <= y && y < H && 0 <= x && x < W; }
auto set(int b, int i) { return b | (1 << i); }
auto get(int b, int i) { return b & (1 << i); }
auto east(int b) {
  auto res = 0;
  for (auto i : EAST)
    if (get(b, i.first))
      res = set(res, i.second);
  return res;
}
auto south(int b) {
  auto res = 0;
  for (auto i : SOUTH)
    if (get(b, i.first))
      res = set(res, i.second);
  return res;
}

int dfs(int y, int x, int b) {
  static vector<vector<vector<int>>> memo(
      H, vector<vector<int>>(W, vector<int>(BIT, NIL)));
  if (!valid(y, x))
    return INF;
  if (y == H - 1 && x == W - 1)
    return 0;
  if (~memo[y][x][b])
    return memo[y][x][b];

  auto buy = 0, nb = b;

  if (S[y][x] && !get(nb, 3)) {
    buy = S[y][x];
    nb = set(nb, 3);
  }

  vector<Point> store;
  for (auto nex : neighbor(y, x)) {
    if (!valid(nex.y, nex.x))
      continue;
    if (!S[nex.y][nex.x])
      continue;
    if (get(nb, nex.i))
      continue;
    store.emplace_back(nex);
  }

  if (store.empty())
    return memo[y][x][b] = min(buy + dfs(y, x + 1, east(nb)),
                               buy + dfs(y + 1, x, south(nb)));

  memo[y][x][b] = INF;
  for (auto ex = 0; ex < store.size(); ++ex) {
    auto dup_buy = buy;
    auto dup_nb = nb;
    for (auto i = 0; i < store.size(); ++i)
      if (i != ex) {
        auto nex = store[i];
        dup_buy += S[nex.y][nex.x];
        dup_nb = set(dup_nb, nex.i);
      }
    memo[y][x][b] = min({memo[y][x][b], dup_buy + dfs(y, x + 1, east(dup_nb)),
                         dup_buy + dfs(y + 1, x, south(dup_nb))});
  }
  return memo[y][x][b];
}

int main() {
  cin >> H >> W;

  for (auto i = 0; i < H; ++i) {
    S.emplace_back();
    string s;
    cin >> s;
    for (auto j : s)
      S[i].emplace_back(j == '.' ? 0 : j - '0');
  }

  cout << dfs(0, 0, 0) << endl;
}

Error: MLE

Fixed submission:

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

const int INF = 3e4;

int H, W;
vector<vector<short>> S;

bool valid(int y, int x) { return 0 <= y && y < H && 0 <= x && x < W; }

int dy(int i) { return (i / 3) - 1; }
int dx(int i) { return (i % 3) - 1; }

bool test(int bit, int i) { return (bit >> i) & 1; }
int bset(int bit, int i) { return bit | (1 << i); }
int east(int bit) { return (bit >> 1) & (0b011011011); }
int south(int bit) { return bit >> 3; }

int dfs(int y, int x, int b) {
  static vector<vector<vector<short>>> memo(
      H, vector<vector<short>>(W, vector<short>(1 << 9, -1)));

  if (!valid(y, x))
    return INF;
  if (~memo[y][x][b])
    return memo[y][x][b];

  int buy = 0;
  auto bit = b;

  if (S[y][x] && !test(bit, 4)) {
    buy = S[y][x];
    bit = bset(bit, 4);
  }

  vector<int> store;
  for (auto i : {1, 3, 5, 7})
    if (!test(bit, i)) {
      auto ny = y + dy(i), nx = x + dx(i);
      if (!valid(ny, nx))
        continue;
      if (!S[ny][nx])
        continue;
      store.emplace_back(i);
    }

  if (store.size() <= 1) {
    auto res = buy;
    if (valid(y + 1, x) || valid(y, x + 1))
      res += min(dfs(y + 1, x, south(bit)), dfs(y, x + 1, east(bit)));
    return memo[y][x][b] = res;
  }

  auto res = INF;
  for (auto r : store) {
    auto nb = bit;
    auto t = buy;
    for (auto i : store)
      if (i != r) {
        auto ny = y + dy(i), nx = x + dx(i);
        nb = bset(nb, i);
        t += S[ny][nx];
      }
    if (valid(y + 1, x) || valid(y, x + 1))
      t += min(dfs(y + 1, x, south(nb)), dfs(y, x + 1, east(nb)));
    res = min(res, t);
  }
  return memo[y][x][b] = res;
}

int main() {
  cin >> H >> W;

  for (auto i = 0; i < H; ++i) {
    S.emplace_back();
    string s;
    cin >> s;
    for (auto j : s)
      S[i].emplace_back(j == '.' ? 0 : j - '0');
  }

  cout << dfs(0, 0, 0) << endl;
}