Problem p03134 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
using std::bitset;
using std::cin;
using std::cout;
using std::endl;
using std::make_pair;
using std::map;
using std::pair;
using std::priority_queue;
using std::queue;
using std::set;
using std::string;
using std::stringstream;
using std::vector;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<ULL, ULL> puu;
#ifdef DEBUG
using std::cerr;
#define pass cerr << "[" << __FUNCTION__ << "] : line = " << __LINE__ << endl;
#define display(x) cerr << #x << " = " << x << endl;
#define displaya(a, st, n)                                                     \
  {                                                                            \
    cerr << #a << " = {";                                                      \
    for (int qwq = (st); qwq <= (n); ++qwq)                                    \
      if (qwq == (st))                                                         \
        cerr << a[qwq];                                                        \
      else                                                                     \
        cerr << ", " << a[qwq];                                                \
    cerr << "}" << endl;                                                       \
  }
#define displayv(a) displaya(a, 0, (int)(a.size() - 1))
#include <ctime>
class MyTimer {
  clock_t st;

public:
  MyTimer() {
    cerr << std::fixed << std::setprecision(0);
    reset();
  }
  ~MyTimer() { report(); }
  void reset() { st = clock_t(); }
  void report() {
    cerr << "Time consumed: " << (clock() - st) * 1e3 / CLOCKS_PER_SEC << "ms"
         << endl;
  }
} myTimer;
#else
#define cerr                                                                   \
  if (false)                                                                   \
  std::cout
#define pass ;
#define display(x) ;
#define displaya(a, st, n) ;
#define displayv(a) ;
class MyTimer {
public:
  void reset() {}
  void report() {}
} myTimer;
#endif

template <typename A, typename B>
std::ostream &operator<<(std::ostream &cout, const pair<A, B> &x) {
  return cout << "(" << x.first << ", " << x.second << ")";
}
template <typename T1, typename T2> inline bool chmin(T1 &a, const T2 &b) {
  return a > b ? a = b, true : false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, const T2 &b) {
  return a < b ? a = b, true : false;
}

const int maxN = 2000 + 5;
const int P = 998244353;
void inc(int &x, int y) { (x += y) >= P ? x -= P : x; }
void dec(int &x, int y) { (x -= y) < 0 ? x += P : x; }
int n;
char s[maxN];
int r[maxN], b[maxN];
int f[maxN][maxN];

int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  memset(r, 0, sizeof(r));
  memset(b, 0, sizeof(b));
  for (int i = 1; i <= n; ++i) {
    if (s[i] == '0')
      r[i] = r[i - 1] + 2, b[i] = b[i - 1];
    if (s[i] == '1')
      r[i] = r[i - 1] + 1, b[i] = b[i - 1] + 1;
    if (s[i] == '2')
      r[i] = r[i - 1], b[i] = b[i - 1] + 2;
  }
  memset(f, 0, sizeof(f));
  f[0][0] = 1;
  for (int R = 0; R <= r[n]; ++R) {
    for (int B = 0; B <= b[n]; ++B) {
      //            printf("f(%d, %d) = %d\n", R, B, f[R][B]);
      int len = std::min(R + B + 1, n);
      if (R < r[len])
        inc(f[R + 1][B], f[R][B]);
      if (B < b[len])
        inc(f[R][B + 1], f[R][B]);
    }
  }
  cout << f[r[n]][b[n]] << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
using std::bitset;
using std::cin;
using std::cout;
using std::endl;
using std::make_pair;
using std::map;
using std::pair;
using std::priority_queue;
using std::queue;
using std::set;
using std::string;
using std::stringstream;
using std::vector;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<ULL, ULL> puu;
#ifdef DEBUG
using std::cerr;
#define pass cerr << "[" << __FUNCTION__ << "] : line = " << __LINE__ << endl;
#define display(x) cerr << #x << " = " << x << endl;
#define displaya(a, st, n)                                                     \
  {                                                                            \
    cerr << #a << " = {";                                                      \
    for (int qwq = (st); qwq <= (n); ++qwq)                                    \
      if (qwq == (st))                                                         \
        cerr << a[qwq];                                                        \
      else                                                                     \
        cerr << ", " << a[qwq];                                                \
    cerr << "}" << endl;                                                       \
  }
#define displayv(a) displaya(a, 0, (int)(a.size() - 1))
#include <ctime>
class MyTimer {
  clock_t st;

public:
  MyTimer() {
    cerr << std::fixed << std::setprecision(0);
    reset();
  }
  ~MyTimer() { report(); }
  void reset() { st = clock_t(); }
  void report() {
    cerr << "Time consumed: " << (clock() - st) * 1e3 / CLOCKS_PER_SEC << "ms"
         << endl;
  }
} myTimer;
#else
#define cerr                                                                   \
  if (false)                                                                   \
  std::cout
#define pass ;
#define display(x) ;
#define displaya(a, st, n) ;
#define displayv(a) ;
class MyTimer {
public:
  void reset() {}
  void report() {}
} myTimer;
#endif

template <typename A, typename B>
std::ostream &operator<<(std::ostream &cout, const pair<A, B> &x) {
  return cout << "(" << x.first << ", " << x.second << ")";
}
template <typename T1, typename T2> inline bool chmin(T1 &a, const T2 &b) {
  return a > b ? a = b, true : false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, const T2 &b) {
  return a < b ? a = b, true : false;
}

const int maxN = 2000 + 5;
const int P = 998244353;
void inc(int &x, int y) { (x += y) >= P ? x -= P : x; }
void dec(int &x, int y) { (x -= y) < 0 ? x += P : x; }
int n;
char s[maxN];
int r[maxN], b[maxN];
int f[maxN * 2][maxN * 2];

int main() {
  scanf("%s", s + 1);
  n = strlen(s + 1);
  memset(r, 0, sizeof(r));
  memset(b, 0, sizeof(b));
  for (int i = 1; i <= n; ++i) {
    if (s[i] == '0')
      r[i] = r[i - 1] + 2, b[i] = b[i - 1];
    if (s[i] == '1')
      r[i] = r[i - 1] + 1, b[i] = b[i - 1] + 1;
    if (s[i] == '2')
      r[i] = r[i - 1], b[i] = b[i - 1] + 2;
  }
  memset(f, 0, sizeof(f));
  f[0][0] = 1;
  for (int R = 0; R <= r[n]; ++R) {
    for (int B = 0; B <= b[n]; ++B) {
      //            printf("f(%d, %d) = %d\n", R, B, f[R][B]);
      int len = std::min(R + B + 1, n);
      if (R < r[len])
        inc(f[R + 1][B], f[R][B]);
      if (B < b[len])
        inc(f[R][B + 1], f[R][B]);
    }
  }
  cout << f[r[n]][b[n]] << endl;
  return 0;
}