Problem p01842 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;

template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

ll inf = -111111111;
ll dp[51][51][51][51][2][2];

ll va[51], vb[51];

ll calc(int a, int b, int c, int d, int e) {
  if (a == c && b == d)
    return 0;
  if (e == 0) {
    if (c - a == d - b) {
      ll x = 0, y = 0;
      int p = c, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        p--;
        q--;
      }

      return x - y;
    } else {
      ll x = 0, y = vb[d];
      if (vb[d] == -1)
        y = 0;
      int p = c, q = d - 1;
      while (1) {
        if (p == a && q == b)
          break;
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        p--;
        q--;
      }
      return x - y;
    }
  } else {
    if (c - a > d - b) {
      ll x = va[c], y = 0;
      if (va[c] == -1)
        x = 0;
      int p = c - 1, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        p--;
        q--;
      }
      return x - y;
    } else {
      ll x = 0, y = 0;
      int p = c, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        p--;
        q--;
      }
      return x - y;
    }
  }
}

int n, m;

ll saiki(int a, int b, int c, int d, int e, int f) {
  // cout << a << " " << b << " " << c << " " << d << " " << e << endl;
  if (dp[a][b][c][d][e][f] != inf) {
    return dp[a][b][c][d][e][f];
  }
  if (e == 0 && a == 0) {
    if (a == c && b == d && f == 0)
      return dp[a][b][c][d][e][f] = saiki(a, b, a, b, 1, 1);
    if (f == 1)
      return 0;
    return dp[a][b][c][d][e][f] = calc(a, b, c, d, e) + saiki(a, b, a, b, 1, 0);
  }
  if (e == 1 && b == 0) {
    if (a == c && b == d && f == 0)
      return dp[a][b][c][d][e][f] = saiki(a, b, a, b, 0, 1);
    if (f == 1)
      return 0;
    return dp[a][b][c][d][e][f] = calc(a, b, c, d, e) + saiki(a, b, a, b, 0, 0);
  }
  if (a == c && b == d) {
    if (e == 0) {
      if (a == n && b == m) {
        ll ma = saiki(a, b, c, d, 1, 1);
        ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
        return dp[a][b][c][d][e][f] = ma;
      } else {
        ll ma;
        if (f == 1) {
          ma = 0;
        } else {
          ma = saiki(a, b, c, d, 1, 1);
        }
        ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
        return dp[a][b][c][d][e][f] = ma;
      }
    } else {
      ll mi;
      if (f == 1)
        mi = 0;
      else
        mi = saiki(a, b, c, d, 0, 1);
      mi = min(mi, saiki(a, b - 1, c, d, 0, 0));
      return dp[a][b][c][d][e][f] = mi;
    }
  } else {
    if (e == 0) {
      ll ma = calc(a, b, c, d, e) + saiki(a, b, a, b, 1, 0);
      ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
      return dp[a][b][c][d][e][f] = ma;
    } else {
      ll mi = calc(a, b, c, d, e) + saiki(a, b, a, b, 0, 0);
      mi = min(mi, saiki(a, b - 1, c, d, 0, 0));
      return dp[a][b][c][d][e][f] = mi;
    }
  }
}

int main() {
  Fill(dp, inf);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> va[n - i];
  }
  for (int i = 0; i < m; i++) {
    cin >> vb[m - i];
  }
  ll ans = saiki(n, m, n, m, 0, 0);
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;

ll dp[51][51][51][51][2][2];

ll va[51], vb[51];

ll calc(int a, int b, int c, int d, int e) {
  if (a == c && b == d)
    return 0;
  if (e == 0) {
    if (c - a == d - b) {
      ll x = 0, y = 0;
      int p = c, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        p--;
        q--;
      }

      return x - y;
    } else {
      ll x = 0, y = vb[d];
      if (vb[d] == -1)
        y = 0;
      int p = c, q = d - 1;
      while (1) {
        if (p == a && q == b)
          break;
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        p--;
        q--;
      }
      return x - y;
    }
  } else {
    if (c - a > d - b) {
      ll x = va[c], y = 0;
      if (va[c] == -1)
        x = 0;
      int p = c - 1, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        p--;
        q--;
      }
      return x - y;
    } else {
      ll x = 0, y = 0;
      int p = c, q = d;
      while (1) {
        if (p == a && q == b)
          break;
        if (vb[q] != -1) {
          y += vb[q];
        } else {
          x = 0;
        }
        if (va[p] != -1) {
          x += va[p];
        } else {
          y = 0;
        }
        p--;
        q--;
      }
      return x - y;
    }
  }
}

int n, m;

ll saiki(int a, int b, int c, int d, int e, int f) {
  // cout << a << " " << b << " " << c << " " << d << " " << e << endl;
  if (dp[a][b][c][d][e][f] != 0) {
    return dp[a][b][c][d][e][f];
  }
  if (e == 0 && a == 0) {
    if (a == c && b == d && f == 0)
      return dp[a][b][c][d][e][f] = saiki(a, b, a, b, 1, 1);
    if (f == 1)
      return 0;
    return dp[a][b][c][d][e][f] = calc(a, b, c, d, e) + saiki(a, b, a, b, 1, 0);
  }
  if (e == 1 && b == 0) {
    if (a == c && b == d && f == 0)
      return dp[a][b][c][d][e][f] = saiki(a, b, a, b, 0, 1);
    if (f == 1)
      return 0;
    return dp[a][b][c][d][e][f] = calc(a, b, c, d, e) + saiki(a, b, a, b, 0, 0);
  }
  if (a == c && b == d) {
    if (e == 0) {
      if (a == n && b == m) {
        ll ma = saiki(a, b, c, d, 1, 1);
        ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
        return dp[a][b][c][d][e][f] = ma;
      } else {
        ll ma;
        if (f == 1) {
          ma = 0;
        } else {
          ma = saiki(a, b, c, d, 1, 1);
        }
        ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
        return dp[a][b][c][d][e][f] = ma;
      }
    } else {
      ll mi;
      if (f == 1)
        mi = 0;
      else
        mi = saiki(a, b, c, d, 0, 1);
      mi = min(mi, saiki(a, b - 1, c, d, 0, 0));
      return dp[a][b][c][d][e][f] = mi;
    }
  } else {
    if (e == 0) {
      ll ma = calc(a, b, c, d, e) + saiki(a, b, a, b, 1, 0);
      ma = max(ma, saiki(a - 1, b, c, d, 1, 0));
      return dp[a][b][c][d][e][f] = ma;
    } else {
      ll mi = calc(a, b, c, d, e) + saiki(a, b, a, b, 0, 0);
      mi = min(mi, saiki(a, b - 1, c, d, 0, 0));
      return dp[a][b][c][d][e][f] = mi;
    }
  }
}

int main() {

  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> va[n - i];
  }
  for (int i = 0; i < m; i++) {
    cin >> vb[m - i];
  }
  ll ans = saiki(n, m, n, m, 0, 0);
  cout << ans << endl;
  return 0;
}