Problem p02828 (C++)

Buggy submission (status: Runtime Error):
#include <cstdio>
#define N 403
#define mod 998244353
using namespace std;
long long newf[N], f[N][N][N], g[N][N][N], C[N][N], th2[N];
int a[N], n;
void dfs(int l, int r, int h) {
  //	g[l][h][0]=1;f[l][h][0]=1;
  int start = 0;
  bool bo = false;
  for (int i = l; i <= r; i++) {
    if (a[i - 1] <= h && a[i] > h && start == 0)
      start = i;
    if (a[i] <= h) {
      if (start != 0) {
        bo = true;
        dfs(start, i - 1, h + 1);
        for (int i = 0; i <= (r - l + 1); i++)
          newf[i] = 0;
        for (int j = (r - l + 1); j >= 0; j--) {
          int sp = f[l][h][j];
          if (j == 0)
            sp = 1;
          if (sp == 0)
            continue;
          for (int k = 0; k <= (i - start); k++)
            newf[j + k] = (newf[j + k] + sp * f[start][h + 1][k] % mod) % mod;
        }
        for (int i = (r - l + 1); i >= 0; i--)
          f[l][h][i] = newf[i];
        for (int i = 0; i <= (r - l + 1); i++)
          newf[i] = 0;
        for (int j = (r - l + 1); j >= 0; j--) {
          int sp = g[l][h][j];
          if (j == 0)
            sp = 1;
          if (sp == 0)
            continue;
          for (int k = 0; k <= (i - start); k++)
            newf[j + k] = (newf[j + k] + sp * g[start][h + 1][k] % mod) % mod;
        }
        for (int i = (r - l + 1); i >= 0; i--)
          g[l][h][i] = newf[i];
      }
      start = 0;
    }
  }
  if (start > 0) {
    bo = true;
    dfs(start, r, h + 1);
    for (int i = 0; i <= (r - l + 1); i++)
      newf[i] = 0;
    for (int j = (r - l + 1); j >= 0; j--) {
      int sp = f[l][h][j];
      if (j == 0)
        sp = 1;
      if (sp == 0)
        continue;
      for (int k = 0; k <= (r - l + 1); k++)
        newf[j + k] = (newf[j + k] + sp * f[start][h + 1][k] % mod) % mod;
    }
    for (int i = (r - l + 1); i >= 0; i--)
      f[l][h][i] = newf[i];
    for (int i = 0; i <= (r - l + 1); i++)
      newf[i] = 0;
    for (int j = (r - l + 1); j >= 0; j--) {
      int sp = g[l][h][j];
      if (j == 0)
        sp = 1;
      if (sp == 0)
        continue;
      for (int k = 0; k <= (r - l + 1); k++)
        newf[j + k] = (newf[j + k] + sp * g[start][h + 1][k] % mod) % mod;
    }
    for (int i = (r - l + 1); i >= 0; i--)
      g[l][h][i] = newf[i];
  }
  int num = 0;
  for (int i = l; i <= r; i++)
    if (a[i] == h)
      num++;
  if (!bo) {
    f[l][h][num] = th2[num] - 1;
    for (int i = 0; i <= r - l + 1; i++)
      g[l][h][i] = C[num][i];
    f[l][h][0] = g[l][h][0];
    return;
  }
  for (int i = 0; i <= (r - l + 1); i++)
    newf[i] = 0;
  for (int i = (r - l + 1); i >= 0; i--) {
    if (f[l][h][i] == 0)
      continue;
    int slen = (r - l + 1) - i - num;
    for (int j = 0; j <= slen; j++) {
      if (j == 0)
        newf[i + j + num] = (newf[i + j + num] + f[l][h][i] * C[slen][j] % mod *
                                                     (th2[i + num] - 1) % mod) %
                            mod;
      else
        newf[i + j + num] = (newf[i + j + num] + f[l][h][i] * C[slen][j] % mod *
                                                     th2[i + num] % mod) %
                            mod;
    }
  }
  for (int i = (r - l + 1); i >= 0; i--)
    f[l][h][i] = newf[i];
  for (int i = 0; i <= (r - l + 1); i++)
    f[l][h][i] = (f[l][h][i] + g[l][h][i]) % mod;
  for (int i = 0; i <= (r - l + 1); i++)
    newf[i] = 0;
  for (int i = 0; i <= (r - l + 1); i++) {
    if (g[l][h][i] == 0)
      continue;
    int slen = (r - l + 1) - i;
    for (int j = 0; j <= slen; j++)
      newf[i + j] =
          (newf[i + j] + g[l][h][i] * C[slen][j] % mod * th2[i] % mod) % mod;
  }
  for (int i = (r - l + 1); i >= 0; i--)
    g[l][h][i] = newf[i];
}
int main() {
  scanf("%d", &n);
  C[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++)
      C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
  }
  th2[0] = 1;
  for (int i = 1; i <= n; i++)
    th2[i] = th2[i - 1] * 2 % mod;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  // num=0;
  dfs(1, n, 1);
  printf("%lld\n", f[1][1][n]);
}

Fixed submission:
#include <cstdio>
#define N 405
#define mod 998244353
using namespace std;
long long newf[N], f[N][N][N], g[N][N][N], C[N][N], th2[N];
int a[N], n;
void dfs(int l, int r, int h) {
  //	g[l][h][0]=1;f[l][h][0]=1;
  int start = 0;
  bool bo = false;
  for (int i = l; i <= r; i++) {
    if (a[i - 1] <= h && a[i] > h && start == 0)
      start = i;
    if (a[i] <= h) {
      if (start != 0) {
        bo = true;
        dfs(start, i - 1, h + 1);
        for (int i = 0; i <= (r - l + 1); i++)
          newf[i] = 0;
        for (int j = (r - l + 1); j >= 0; j--) {
          int sp = f[l][h][j];
          if (j == 0)
            sp = 1;
          if (sp == 0)
            continue;
          for (int k = 0; k <= (i - start); k++)
            newf[j + k] = (newf[j + k] + sp * f[start][h + 1][k] % mod) % mod;
        }
        for (int i = (r - l + 1); i >= 0; i--)
          f[l][h][i] = newf[i];
        for (int i = 0; i <= (r - l + 1); i++)
          newf[i] = 0;
        for (int j = (r - l + 1); j >= 0; j--) {
          int sp = g[l][h][j];
          if (j == 0)
            sp = 1;
          if (sp == 0)
            continue;
          for (int k = 0; k <= (i - start); k++)
            newf[j + k] = (newf[j + k] + sp * g[start][h + 1][k] % mod) % mod;
        }
        for (int i = (r - l + 1); i >= 0; i--)
          g[l][h][i] = newf[i];
      }
      start = 0;
    }
  }
  if (start > 0) {
    bo = true;
    dfs(start, r, h + 1);
    for (int i = 0; i <= (r - l + 1); i++)
      newf[i] = 0;
    for (int j = (r - l + 1); j >= 0; j--) {
      int sp = f[l][h][j];
      if (j == 0)
        sp = 1;
      if (sp == 0)
        continue;
      for (int k = 0; k <= (r - l + 1); k++)
        newf[j + k] = (newf[j + k] + sp * f[start][h + 1][k] % mod) % mod;
    }
    for (int i = (r - l + 1); i >= 0; i--)
      f[l][h][i] = newf[i];
    for (int i = 0; i <= (r - l + 1); i++)
      newf[i] = 0;
    for (int j = (r - l + 1); j >= 0; j--) {
      int sp = g[l][h][j];
      if (j == 0)
        sp = 1;
      if (sp == 0)
        continue;
      for (int k = 0; k <= (r - l + 1); k++)
        newf[j + k] = (newf[j + k] + sp * g[start][h + 1][k] % mod) % mod;
    }
    for (int i = (r - l + 1); i >= 0; i--)
      g[l][h][i] = newf[i];
  }
  int num = 0;
  for (int i = l; i <= r; i++)
    if (a[i] == h)
      num++;
  if (!bo) {
    f[l][h][num] = th2[num] - 1;
    for (int i = 0; i <= r - l + 1; i++)
      g[l][h][i] = C[num][i];
    f[l][h][0] = g[l][h][0];
    return;
  }
  for (int i = 0; i <= (r - l + 1); i++)
    newf[i] = 0;
  for (int i = (r - l + 1); i >= 0; i--) {
    if (f[l][h][i] == 0)
      continue;
    int slen = (r - l + 1) - i - num;
    for (int j = 0; j <= slen; j++) {
      if (j == 0)
        newf[i + j + num] = (newf[i + j + num] + f[l][h][i] * C[slen][j] % mod *
                                                     (th2[i + num] - 1) % mod) %
                            mod;
      else
        newf[i + j + num] = (newf[i + j + num] + f[l][h][i] * C[slen][j] % mod *
                                                     th2[i + num] % mod) %
                            mod;
    }
  }
  for (int i = (r - l + 1); i >= 0; i--)
    f[l][h][i] = newf[i];
  for (int i = 0; i <= (r - l + 1); i++)
    f[l][h][i] = (f[l][h][i] + g[l][h][i]) % mod;
  for (int i = 0; i <= (r - l + 1); i++)
    newf[i] = 0;
  for (int i = 0; i <= (r - l + 1); i++) {
    if (g[l][h][i] == 0)
      continue;
    int slen = (r - l + 1) - i;
    for (int j = 0; j <= slen; j++)
      newf[i + j] =
          (newf[i + j] + g[l][h][i] * C[slen][j] % mod * th2[i] % mod) % mod;
  }
  for (int i = (r - l + 1); i >= 0; i--)
    g[l][h][i] = newf[i];
}
int main() {
  scanf("%d", &n);
  C[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++)
      C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
  }
  th2[0] = 1;
  for (int i = 1; i <= n; i++)
    th2[i] = th2[i - 1] * 2 % mod;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  // num=0;
  dfs(1, n, 1);
  printf("%lld\n", f[1][1][n]);
}