Problem p03488 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <numeric>
#include <vector>

using namespace std;

bool check(const vector<int> &v, int hf) {
  // 0 dp初期値
  // 要素数分(1 indexed)
  // 要素を -1 で初期化
  vector<int> dp(hf + 1, -1);

  dp[0] = 0;

  for (int i = 0; i < (signed)v.size(); i++) {
    for (int j = 0; j <= hf; j++) {
      // 最大で「1」 「0」→「1」 「1」→「1」
      if (0 <= dp[j])
        dp[j] = 1;
      // 組合せで構築できない「-1」
      else if (j < v[i] || dp[j - v[i]] <= 0)
        dp[j] = -1;
      // 組合せで構築できる「0」
      else
        dp[j] = 0;
    }
  }

  return 0 <= dp[hf];
}

int main() {
  const char *Yes = "Yes";
  const char *No = "No";

  // char s[8001];
  char s[31];
  if (scanf("%s", s) < 1)
    return 0;

  int x, y;
  if (scanf("%d%d", &x, &y) < 2)
    return 0;

  // 要素数 2 (x と y)
  array<vector<int>, 2> ar;

  int xy = 0, cnt = 0;

  for (int i = 0; i < (signed)strlen(s); i++) {
    if (s[i] == 'F') {
      cnt++;
    } else {
      ar[xy].push_back(cnt);
      cnt = 0;
      xy ^= 1; // ビット排他的論理和 反転(0 ⇔ 1)
    }
  }

  // 最後が T でない場合の考慮
  ar[xy].push_back(cnt);

  // x の先頭を参照
  // 最初だけ 右確定 目標地点を左にずらす
  x -= ar[0][0];

  // x の先頭を削除
  ar[0].erase(ar[0].begin());

  // 正負を意識する必要はない
  // 先に左にずらしている為
  x = abs(x);
  // y は 0 始点の為
  y = abs(y);

  // x 合計
  int xs = accumulate(ar[0].begin(), ar[0].end(), 0);
  // y 合計
  int ys = accumulate(ar[1].begin(), ar[1].end(), 0);

  // 不足
  if (xs < x || ys < y)
    return !printf("%s\n", No);

  // 全力 Just
  if (xs == x && ys == y)
    return !printf("%s\n", Yes);

  // 奇数 行って帰れず
  if ((xs - x) % 2 || (ys - y) % 2)
    return !printf("%s\n", No);

  // 行き過ぎ 確定
  // ソート 昇順
  sort(ar[0].begin(), ar[0].end()); // x
  sort(ar[1].begin(), ar[1].end()); // y

  if (check(ar[0], (xs - x) / 2) && check(ar[1], (ys - y) / 2)) {
    // 行き過ぎた距離の半分を
    // 組合せで構築できる
    return !printf("%s\n", Yes);
  } else {
    // 行き過ぎた距離の半分を
    // 組合せで構築できない
    return !printf("%s\n", No);
  }
}

Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <array>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <numeric>
#include <vector>

using namespace std;

bool check(const vector<int> &v, int hf) {
  // 0 dp初期値
  // 要素数分(1 indexed)
  // 要素を -1 で初期化
  vector<int> dp(hf + 1, -1);

  dp[0] = 0;

  for (int i = 0; i < (signed)v.size(); i++) {
    for (int j = 0; j <= hf; j++) {
      // 最大で「1」 「0」→「1」 「1」→「1」
      if (0 <= dp[j])
        dp[j] = 1;
      // 組合せで構築できない「-1」
      else if (j < v[i] || dp[j - v[i]] <= 0)
        dp[j] = -1;
      // 組合せで構築できる「0」
      else
        dp[j] = 0;
    }
  }

  return 0 <= dp[hf];
}

int main() {
  const char *Yes = "Yes";
  const char *No = "No";

  char s[8001];
  if (scanf("%s", s) < 1)
    return 0;

  int x, y;
  if (scanf("%d%d", &x, &y) < 2)
    return 0;

  // 要素数 2 (x と y)
  array<vector<int>, 2> ar;

  int xy = 0, cnt = 0;

  for (int i = 0; i < (signed)strlen(s); i++) {
    if (s[i] == 'F') {
      cnt++;
    } else {
      ar[xy].push_back(cnt);
      cnt = 0;
      xy ^= 1; // ビット排他的論理和 反転(0 ⇔ 1)
    }
  }

  // 最後が T でない場合の考慮
  ar[xy].push_back(cnt);

  // x の先頭を参照
  // 最初だけ 右確定 目標地点を左にずらす
  x -= ar[0][0];

  // x の先頭を削除
  ar[0].erase(ar[0].begin());

  // 正負を意識する必要はない
  // 先に左にずらしている為
  x = abs(x);
  // y は 0 始点の為
  y = abs(y);

  // x 合計
  int xs = accumulate(ar[0].begin(), ar[0].end(), 0);
  // y 合計
  int ys = accumulate(ar[1].begin(), ar[1].end(), 0);

  // 不足
  if (xs < x || ys < y)
    return !printf("%s\n", No);

  // 全力 Just
  if (xs == x && ys == y)
    return !printf("%s\n", Yes);

  // 奇数 行って帰れず
  if ((xs - x) % 2 || (ys - y) % 2)
    return !printf("%s\n", No);

  // 行き過ぎ 確定
  // ソート 昇順
  sort(ar[0].begin(), ar[0].end()); // x
  sort(ar[1].begin(), ar[1].end()); // y

  if (check(ar[0], (xs - x) / 2) && check(ar[1], (ys - y) / 2)) {
    // 行き過ぎた距離の半分を
    // 組合せで構築できる
    return !printf("%s\n", Yes);
  } else {
    // 行き過ぎた距離の半分を
    // 組合せで構築できない
    return !printf("%s\n", No);
  }
}