Problem p03134 (C++)

Buggy submission (status: Runtime Error):
#define _USE_MATH_DEFINES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

typedef long long int64;
typedef pair<int, int> ii;
const int INF = 1 << 29;
const int MOD = 998244353;

const int N = 2e3 + 10;
char s[N];
int dp[N][N];
int A[N], B[N];
int n;

int solve(int x, int y, int step) {
  if (x + y == 2 * n)
    return 1;
  step = min(step, n);
  int &ret = dp[x][y];
  if (ret >= 0)
    return ret;
  ret = 0;
  // trace(x, y, step, A[step], B[step]);
  if (A[step] > x)
    ret = (ret + solve(x + 1, y, step + 1)) % MOD;
  if (B[step] > y)
    ret = (ret + solve(x, y + 1, step + 1)) % MOD;
  // trace(x, y, ret);
  return ret;
}

int main() {
  scanf("%s", s);
  n = strlen(s);
  for (int i = 0; i < n; ++i) {
    if (s[i] == '0') {
      A[i + 1] = A[i] + 2;
      B[i + 1] = B[i];
    } else if (s[i] == '1') {
      A[i + 1] = A[i] + 1;
      B[i + 1] = B[i] + 1;
    } else {
      A[i + 1] = A[i];
      B[i + 1] = B[i] + 2;
    }
  }
  memset(dp, 255, sizeof(dp));
  int ret = solve(0, 0, 1);
  printf("%d\n", ret);
  return 0;
}


Fixed submission:
#define _USE_MATH_DEFINES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

typedef long long int64;
typedef pair<int, int> ii;
const int INF = 1 << 29;
const int MOD = 998244353;

const int N = 5e3 + 10;
char s[N];
int dp[N][N];
int A[N], B[N];
int n;

int solve(int x, int y, int step) {
  if (x + y == 2 * n)
    return 1;
  step = min(step, n);
  int &ret = dp[x][y];
  if (ret >= 0)
    return ret;
  ret = 0;
  // trace(x, y, step, A[step], B[step]);
  if (A[step] > x)
    ret = (ret + solve(x + 1, y, step + 1)) % MOD;
  if (B[step] > y)
    ret = (ret + solve(x, y + 1, step + 1)) % MOD;
  // trace(x, y, ret);
  return ret;
}

int main() {
  scanf("%s", s);
  n = strlen(s);
  for (int i = 0; i < n; ++i) {
    if (s[i] == '0') {
      A[i + 1] = A[i] + 2;
      B[i + 1] = B[i];
    } else if (s[i] == '1') {
      A[i + 1] = A[i] + 1;
      B[i + 1] = B[i] + 1;
    } else {
      A[i + 1] = A[i];
      B[i + 1] = B[i] + 2;
    }
  }
  memset(dp, 255, sizeof(dp));
  int ret = solve(0, 0, 1);
  printf("%d\n", ret);
  return 0;
}