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

#include <algorithm>
#include <cstring>
#include <iostream>

const int INF = 1 << 30;

int W, H, K;
// 00 → 右 01 → 下 10 → 左 11 → 上
int memo[1 << 12][4][50][50];
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
char field[50][50];
int mask;

int rec(int bit, int k, int y, int x) {
  if (memo[bit][k][y][x] != -1)
    return memo[bit][k][y][x];

  if (y == H - 1 && x == W - 1 && !k)
    return 0;

  int tx = x, ty = y;
  bool f = false;
  for (int i = 0; i != 2 * K; ++i) {
    tx -= dx[(bit >> (2 * i)) & 3];
    ty -= dy[(bit >> (2 * i)) & 3];

    if (tx == x && ty == y) {
      f = true;
      break;
    }
  }

  int ret = 0;

  if (!f && field[y][x] >= '0' && field[y][x] <= '9')
    ret += field[y][x] - '0';

  int ans = -INF;

  for (int i = 0; i != 4; ++i) {
    if (!k && i >= 2)
      break;

    int nx = x + dx[i], ny = y + dy[i];
    if (nx >= 0 && nx < W && ny >= 0 && ny < H && field[ny][nx] != '#')
      ans = std::max(ans,
                     rec(((bit << 2) | i) & mask, k - (i >= 2), ny, nx) + ret);
  }

  return memo[bit][k][y][x] = ans;
}

int main() {
  std::cin >> H >> W >> K;

  mask = (1 << (4 * K)) - 1;

  for (int i = 0; i != H; ++i)
    for (int j = 0; j != W; ++j)
      std::cin >> field[i][j];

  memset(memo, -1, sizeof(memo));
  int ans = rec(0, K, 0, 0);
  std::cout << (ans < 0 ? 0 : ans) << std::endl;

  return 0;
}

Error: TLE

Fixed submission:

// JOI 2012-2013 予選6
#include <algorithm>
#include <iostream>
#include <map>
#include <utility>
#include <vector>

typedef std::pair<int, int> P;

const int INF = 1 << 30;

int H, W, K;
char field[50][51];

struct state {
  int x, y, k;
  std::vector<P> visited;

  state(int x, int y, int k, const std::vector<P> &v)
      : x(x), y(y), k(k), visited(v) {}

  bool operator<(const state &rhs) const {
    return std::make_pair(P(x, y), std::make_pair(k, visited)) <
           std::make_pair(P(rhs.x, rhs.y), std::make_pair(rhs.k, rhs.visited));
  }
};

std::map<state, int> memo;

int rec(int x, int y, int k, const std::vector<P> &visited) {
  state cur(x, y, k, visited);

  if (memo.find(cur) != memo.end())
    return memo[cur];

  int ret = -INF;

  if (x == H - 1 && y == W - 1)
    ret = 0;

  static const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

  for (int d = 0; d != 4; ++d) {
    int nx = x + dx[d], ny = y + dy[d];
    int nk = d >= 2 ? k - 1 : k;

    if (nx < 0 || nx >= H || ny < 0 || ny >= W || nk < 0 ||
        field[nx][ny] == '#')
      continue;

    std::vector<P> nv;
    for (int i = 0; i != visited.size(); ++i)
      if (std::max(nx - visited[i].first, 0) +
              std::max(ny - visited[i].second, 0) <=
          nk)
        nv.push_back(visited[i]);

    if (field[nx][ny] != '.') {
      nv.push_back(P(nx, ny));
      std::sort(nv.begin(), nv.end());
      nv.erase(std::unique(nv.begin(), nv.end()), nv.end());
    }

    int val = field[nx][ny] != '.' ? field[nx][ny] - '0' : 0;
    for (int i = 0; i != visited.size(); ++i)
      if (visited[i] == P(nx, ny))
        val = 0;

    ret = std::max(ret, rec(nx, ny, nk, nv) + val);
  }

  return memo[cur] = ret;
}

int main() {
  std::cin >> H >> W >> K;
  for (int i = 0; i != H; ++i)
    std::cin >> field[i];

  std::cout << rec(0, 0, K, std::vector<P>()) << std::endl;

  return 0;
}