Problem p00504 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

#define SIZE 500000

#define MAX_H 100
#define MAX_W 100

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

int memo[50][50][1 << 12][4];

int mo[5] = {0, -1, 0, 1, 0};

int dfs(int y, int x, int visit, int k, int h = 0) {
  int ret = -INF;
  bool visit_mm[50][50] = {0};

  // cerr << "(" << y << "," << x << ")" << endl;

  if (memo[y][x][visit][k] > 0)
    return memo[y][x][visit][k];

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

  int after_visit = (visit % (1 << 10));
  int after_x = x, after_y = y;
  int calc_visit = visit;

  vector<pair<int, int>> vec;

  for (int i = 0; i < min(h, 6); i++) {
    after_x -= mo[calc_visit % 4];
    after_y -= mo[calc_visit % 4 + 1];
    calc_visit /= 4;
    visit_mm[after_y][after_x] = true;

    // cerr << "<- (" << after_y << "," << after_x << ")" << endl;
  }

  int add = 1;

  for (int i = 0; i < 4; i++) {
    if (k >= 1 || i >= 2) {
      int to_x = x + mo[i];
      int to_y = y + mo[i + 1];

      if (to_x < 0 || W <= to_x || to_y < 0 || H <= to_y ||
          mm[to_y][to_x] == '#')
        continue;

      if (visit_mm[to_y][to_x])
        add = 0;
      else
        add = mm[to_y][to_x] - '0';

      ret = max(ret, dfs(to_y, to_x, after_visit * 4 + i, k - (i <= 1), h + 1) +
                         add);
    }
  }

  return memo[y][x][visit][k] = ret;
}

int main() {

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

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

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (mm[i][j] == '.')
        mm[i][j] = '0';
    }
  }

  printf("%d\n", dfs(0, 0, 0, K));

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

#define SIZE 500000

#define MAX_H 100
#define MAX_W 100

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

int memo[50][50][1 << 12][4];

int mo[5] = {0, -1, 0, 1, 0};

int dfs(int y, int x, int visit, int k, int h = 0) {
  int ret = -INF;
  bool visit_mm[50][50] = {0};

  // cerr << "(" << y << "," << x << ")" << endl;

  if (memo[y][x][visit][k] != 0)
    return memo[y][x][visit][k];

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

  int after_visit = (visit % (1 << 10));
  int after_x = x, after_y = y;
  int calc_visit = visit;

  vector<pair<int, int>> vec;

  for (int i = 0; i < min(h, 6); i++) {
    after_x -= mo[calc_visit % 4];
    after_y -= mo[calc_visit % 4 + 1];
    calc_visit /= 4;
    visit_mm[after_y][after_x] = true;

    // cerr << "<- (" << after_y << "," << after_x << ")" << endl;
  }

  int add = 1;

  for (int i = 0; i < 4; i++) {
    if (k >= 1 || i >= 2) {
      int to_x = x + mo[i];
      int to_y = y + mo[i + 1];

      if (to_x < 0 || W <= to_x || to_y < 0 || H <= to_y ||
          mm[to_y][to_x] == '#')
        continue;

      if (visit_mm[to_y][to_x])
        add = 0;
      else
        add = mm[to_y][to_x] - '0';

      ret = max(ret, dfs(to_y, to_x, after_visit * 4 + i, k - (i <= 1), h + 1) +
                         add);
    }
  }

  return memo[y][x][visit][k] = ret;
}

int main() {

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

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

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (mm[i][j] == '.')
        mm[i][j] = '0';
    }
  }

  printf("%d\n", dfs(0, 0, 0, K));

  return 0;
}