Problem p00547 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define chmin(a, b)                                                            \\
  if ((a) > (b))                                                               \\
    a = (b);
#define INF (1 << 29)

int dp[1000][1000][16];
int h, w;
string str[1000];
int cost[1000][1000];

bool check(int x, int y) { return x >= 0 && x < w && y >= 0 && y < h; }

int main() {
  cin >> h >> w;
  REP(i, h) cin >> str[i];
  REP(i, h) REP(j, w) if (str[i][j] != '.') cost[i][j] = str[i][j] - '0';

  fill(dp[0][0], dp[h][0], INF);

  dp[0][0][0] = 0;
  REP(i, h) REP(j, w) REP(k, 1 << 4) {
    if (dp[i][j][k] == INF)
      continue;

    int c[3];
    int nextc, nextk, buy;
    int dx[2] = {0, 1}, dy[2] = {1, 0};

    REP(p, 2) {
      if (p == 0) {
        if (i == h - 1)
          continue;
        c[0] = check(j + 1, i + 1) ? cost[i + 1][j + 1] : 0; // right
        c[1] = check(j, i + 2) ? cost[i + 2][j] : 0;         // down
        c[2] = check(j - 1, i + 1) ? cost[i + 1][j - 1] : 0; // left

        nextc = dp[i][j][k] + (!(k & 4) ? cost[i + 1][j] : 0);
        nextk = k & 2 ? 1 : 0;
      } else {
        if (j == w - 1)
          continue;
        c[0] = check(j + 2, i) ? cost[i][j + 2] : 0;         // right
        c[1] = check(j + 1, i + 1) ? cost[i + 1][j + 1] : 0; // down
        c[2] = check(j + 1, i - 1) ? cost[i - 1][j + 1] : 0; // up

        nextc = dp[i][j][k] + (!(k & 2) ? cost[i][j + 1] : 0);
        nextk = k & 4 ? 8 : 0;
      }

      buy = 7; // ????????????????????? 0, 1, 2
      if (!c[0])
        buy -= 1;
      if (!c[1])
        buy -= 2;
      if (!c[2] || k & (p == 0 ? 8 : 1))
        buy -= 4;

      if (buy == 0 || buy == 1 || buy == 2 || buy == 4) {
        chmin(dp[i + dy[p]][j + dx[p]][nextk], nextc);
      } else if (buy == 3 || buy == 6 || buy == 5) {
        int tmp[3] = {2, 4, 0};
        REP(l, 3)
        if (1 << l & buy)
            chmin(dp[i + dy[p]][j + dx[p]][nextk | tmp[l]], nextc + c[l]);
      } else if (buy == 7) {
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 6], nextc + c[0] + c[1]);
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 4], nextc + c[1] + c[2]);
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 2], nextc + c[2] + c[0]);
      }
    }
  }

  cout << dp[h - 1][w - 1][0] << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define chmin(a, b)                                                            \\
  if ((a) > (b))                                                               \\
    a = (b);
#define INF (1 << 29)

int dp[1000][1000][16];
int h, w;
string str[1000];
int cost[1000][1000];

bool check(int x, int y) { return x >= 0 && x < w && y >= 0 && y < h; }

int main() {
  cin >> h >> w;
  REP(i, h) cin >> str[i];
  REP(i, h) REP(j, w) {
    if (str[i][j] == '.')
      cost[i][j] = 0;
    else
      cost[i][j] = str[i][j] - '0';
  }

  fill(dp[0][0], dp[h][0], INF);

  dp[0][0][0] = 0;
  REP(i, h) REP(j, w) REP(k, 1 << 4) {
    if (dp[i][j][k] == INF)
      continue;

    int c[3];
    int nextc, nextk, buy;
    int dx[2] = {0, 1}, dy[2] = {1, 0};

    REP(p, 2) {
      if (p == 0) {
        c[0] = check(j + 1, i + 1) ? cost[i + 1][j + 1] : 0; // right
        c[1] = check(j, i + 2) ? cost[i + 2][j] : 0;         // down
        c[2] = check(j - 1, i + 1) ? cost[i + 1][j - 1] : 0; // left

        nextc = dp[i][j][k] + (!(k & 4) ? cost[i + 1][j] : 0);
        nextk = k & 2 ? 1 : 0;
      } else {
        c[0] = check(j + 2, i) ? cost[i][j + 2] : 0;         // right
        c[1] = check(j + 1, i + 1) ? cost[i + 1][j + 1] : 0; // down
        c[2] = check(j + 1, i - 1) ? cost[i - 1][j + 1] : 0; // up

        nextc = dp[i][j][k] + (!(k & 2) ? cost[i][j + 1] : 0);
        nextk = k & 4 ? 8 : 0;
      }

      buy = 7; // ????????????????????? 0, 1, 2
      if (!c[0])
        buy -= 1;
      if (!c[1])
        buy -= 2;
      if (!c[2] || k & (p == 0 ? 8 : 1))
        buy -= 4;

      if (buy == 0 || buy == 1 || buy == 2 || buy == 4) {
        chmin(dp[i + dy[p]][j + dx[p]][nextk], nextc);
      } else if (buy == 3 || buy == 6 || buy == 5) {
        int tmp[3] = {2, 4, 0};
        REP(l, 3)
        if (1 << l & buy)
            chmin(dp[i + dy[p]][j + dx[p]][nextk | tmp[l]], nextc + c[l]);
      } else if (buy == 7) {
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 6], nextc + c[0] + c[1]);
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 4], nextc + c[1] + c[2]);
        chmin(dp[i + dy[p]][j + dx[p]][nextk | 2], nextc + c[2] + c[0]);
      }
    }
  }

  cout << dp[h - 1][w - 1][0] << endl;
  return 0;
}