Problem p00572 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 3000

enum Type {
  TATE,
  YOKO,
  NONE,
};

int H, W;
int dp[3][NUM + 1];
char base_map[NUM][NUM + 1];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

int calc(int start_row, int start_col) {

  int ret = 0;

  for (int col = start_col; col <= W - 1; col++) {
    dp[TATE][col] = 0;
    dp[YOKO][col] = 0;
    dp[NONE][col] = 0;
  }

  int row = start_row;
  for (int col = start_col; col <= W - 1; col++) {
    if (base_map[row][col] != 'G') {
      if (col == start_col) {
        // Do nothing
      } else {
        dp[NONE][col] =
            max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
      }
    } else { // base_map[row][col] == 'G'
      if (rangeCheck(row - 1, col) == true && base_map[row - 1][col] == 'R' &&
          rangeCheck(row + 1, col) == true &&
          base_map[row + 1][col] == 'W') { // 縦に作れる

        if (col == start_col) {
          dp[TATE][col] = 1;
        } else {
          dp[TATE][col] = max(dp[TATE][col - 1], dp[NONE][col - 1]) + 1;
        }
        ret = max(ret, dp[TATE][col]);
      }
      if (rangeCheck(row, col - 1) == true && base_map[row][col - 1] == 'R' &&
          rangeCheck(row, col + 1) == true &&
          base_map[row][col + 1] == 'W') { // 横に作れる

        if (col == start_col) {
          dp[YOKO][col] = 1;
        } else {
          dp[YOKO][col] = max(dp[YOKO][col - 1], dp[NONE][col - 1]) + 1;
        }
        ret = max(ret, dp[YOKO][col]);
      }
      // どちらも作らない
      if (col == start_col) {
        // Do nothing
      } else {
        dp[NONE][col] =
            max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
      }
    }
    row--;
  }
  return ret;
}

int main() {

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

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

  int ans = 0;
  for (int row = 1; row <= H - 1; row++) {
    ans += calc(row, 0);
  }
  for (int col = 1; col <= W - 1; col++) {
    ans += calc(H - 1, col);
  }

  printf("%d\n", ans);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 3000

enum Type {
  TATE,
  YOKO,
  NONE,
};

int H, W;
int dp[3][NUM + 1];
char base_map[NUM][NUM + 1];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

int calc(int start_row, int start_col) {

  int ret = 0;

  for (int col = start_col; col <= W - 1; col++) {
    dp[TATE][col] = 0;
    dp[YOKO][col] = 0;
    dp[NONE][col] = 0;
  }

  int row = start_row;
  for (int col = start_col; col <= W - 1 && row >= 0; col++) {
    if (base_map[row][col] != 'G') {
      if (col == start_col) {
        // Do nothing
      } else {
        dp[NONE][col] =
            max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
      }
    } else { // base_map[row][col] == 'G'
      if (rangeCheck(row - 1, col) == true && base_map[row - 1][col] == 'R' &&
          rangeCheck(row + 1, col) == true &&
          base_map[row + 1][col] == 'W') { // 縦に作れる

        if (col == start_col) {
          dp[TATE][col] = 1;
        } else {
          dp[TATE][col] = max(dp[TATE][col - 1], dp[NONE][col - 1]) + 1;
        }
        ret = max(ret, dp[TATE][col]);
      }
      if (rangeCheck(row, col - 1) == true && base_map[row][col - 1] == 'R' &&
          rangeCheck(row, col + 1) == true &&
          base_map[row][col + 1] == 'W') { // 横に作れる

        if (col == start_col) {
          dp[YOKO][col] = 1;
        } else {
          dp[YOKO][col] = max(dp[YOKO][col - 1], dp[NONE][col - 1]) + 1;
        }
        ret = max(ret, dp[YOKO][col]);
      }
      // どちらも作らない
      if (col == start_col) {
        // Do nothing
      } else {
        dp[NONE][col] =
            max(dp[NONE][col - 1], max(dp[TATE][col - 1], dp[YOKO][col - 1]));
      }
    }
    row--;
  }
  return ret;
}

int main() {

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

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

  int ans = 0;
  for (int row = 1; row <= H - 1; row++) {
    ans += calc(row, 0);
  }
  for (int col = 1; col <= W - 1; col++) {
    ans += calc(H - 1, col);
  }

  printf("%d\n", ans);

  return 0;
}