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

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

typedef pair<int, int> Pair;
typedef pair<Pair, Pair> PP;

int H;
int W;
int K;
int ans;
char field[114][514];
vector<Pair> around;
queue<PP> q;
map<PP, bool> calced;
map<Pair, int> rev;
map<int, int> dp[114][114][4];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
bool nocost[] = {0, 0, 1, 1};

bool WithinRange(int y, int x) {
  if (y < 0 || H <= y)
    return false;
  if (x < 0 || W <= x)
    return false;
  return true;
}

int ShiftHash(int hash, int dy, int dx) {
  int ret = 0;
  for (Pair p : around) {
    int y, x;
    tie(y, x) = p;
    int py = y + dy;
    int px = x + dx;
    if (rev.count(Pair(py, px))) {
      int v = hash >> rev[Pair(py, px)] & 1;
      ret |= v << rev[p];
    }
  }
  return ret;
}

int main() {
  scanf("%d%d%d", &H, &W, &K);
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      scanf(" %c", &field[i][j]);
      if (field[i][j] == '.')
        field[i][j] = '0';
    }
  }

  for (int i = -3; i <= 3; i++) {
    for (int j = -3; j <= 3; j++) {
      if (i == 0 && j == 0)
        continue;
      if (abs(i) + abs(j) <= 3) {
        rev[Pair(i, j)] = around.size();
        around.emplace_back(Pair(i, j));
      }
    }
  }

  dp[0][0][K][0] = 0;
  q.push(PP(Pair(0, 0), Pair(K, 0)));
  while (!q.empty()) {
    PP pp = q.front();
    q.pop();
    int y, x, k, hash;
    tie(y, x) = pp.first;
    tie(k, hash) = pp.second;
    if (field[y][x] == '#')
      continue;
    if (calced.count(pp))
      continue;
    calced[pp] = true;

    int val = dp[y][x][k][hash];
    // printf("(%d, %d, %d, %d): %d\\n", y, x, k, hash, val);
    if (y == H - 1 && x == W - 1) {
      ans = max(ans, val);
    }

    for (int i = 0; i < 4; i++) {
      int ny = y + dy[i];
      int nx = x + dx[i];
      if (!WithinRange(ny, nx))
        continue;
      if (field[ny][nx] == '#')
        continue;

      int plus = field[ny][nx] - '0';
      if (hash >> rev[Pair(dy[i], dx[i])] & 1)
        plus = 0;

      int nk = k;
      if (!nocost[i]) {
        if (k == 0)
          continue;
        nk = k - 1;
      }

      int nhash = ShiftHash(hash, dy[i], dx[i]);
      nhash |= 1 << rev[Pair(-dy[i], -dx[i])];
      for (Pair p : around) {
        int a, b;
        tie(a, b) = p;
        int d = -(min(a, 0) + min(b, 0));
        if (d > nk)
          nhash &= ~(1 << rev[p]);
      }

      dp[ny][nx][nk][nhash] = max(dp[ny][nx][nk][nhash], val + plus);
      q.push(PP(Pair(ny, nx), Pair(nk, nhash)));
    }
  }
  printf("%d\\n", ans);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <utility>
#include <vector>

using namespace std;

#define INF 0x7fffffff

typedef pair<int, int> Coor;

int h, w, k;
char field[50][50];
map<vector<Coor>, int> dp[50][50][4]; // dp[y][x][left][where]

int dfs(int x, int y, int k, const vector<Coor> &v) {
  vector<Coor> v2;
  int dx[] = {0, 1};
  int dy[] = {1, 0};
  int kdx[] = {0, -1};
  int kdy[] = {-1, 0};
  int ans = -INF;
  if (x == w - 1 && y == h - 1)
    ans = 0;

  for (int i = 0; i < v.size(); i++) {
    Coor c = v[i];
    if (abs(c.first - x) + abs(c.second - y) <= 3) {
      v2.push_back(c);
    }
  }
  sort(v2.begin(), v2.end());

  if (dp[x][y][k].find(v2) != dp[x][y][k].end()) {
    return dp[x][y][k][v2];
  }

  for (int t = 0; t < 2; t++) {
    int newx = x + dx[t];
    int newy = y + dy[t];
    int add = 0;
    bool pushed = false;

    if (newx < 0 || w <= newx || newy < 0 || h <= newy)
      continue;
    if (field[newy][newx] == '#')
      continue;
    if ('1' <= field[newy][newx] && field[newy][newx] <= '9') {
      if (binary_search(v2.begin(), v2.end(), Coor(newx, newy)) == false) {
        add = field[newy][newx] - '0';
        v2.push_back(Coor(newx, newy));
        pushed = true;
      }
    }

    ans = max(ans, dfs(newx, newy, k, v2) + add);
    if (pushed)
      v2.pop_back();
  }

  for (int t = 0; t < 2; t++) {
    int newx = x + kdx[t];
    int newy = y + kdy[t];
    int add = 0;
    bool pushed = false;

    if (newx < 0 || w <= newx || newy < 0 || h <= newy || k == 0)
      continue;
    if (field[newy][newx] == '#')
      continue;
    if ('1' <= field[newy][newx] && field[newy][newx] <= '9') {
      if (binary_search(v2.begin(), v2.end(), Coor(newx, newy)) == false) {
        add = field[newy][newx] - '0';
        v2.push_back(Coor(newx, newy));
        pushed = true;
      }
    }

    ans = max(ans, dfs(newx, newy, k - 1, v2) + add);
    if (pushed)
      v2.pop_back();
  }

  dp[x][y][k][v] = ans;
  return ans;
}

int main() {
  vector<Coor> v;

  scanf("%d %d %d", &h, &w, &k);
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      scanf(" %c", &field[i][j]);
    }
  }

  printf("%d\\n", dfs(0, 0, k, v));
}