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

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int INF = 1e9;

int N, M;
vector<int> A, B;
int dp[51][51][51][51][2][3];

int dfs(int n, int m, int a, int b, int t, int con) {
  if (con == 2)
    return 0;
  if (n == N && m == M) {
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    if (!t) {
      while (1) {
        if (mm < b)
          break;
        if (B[mm] < 0)
          fa = false;
        if (fb && B[mm] >= 0)
          sumB += B[mm];
        if (nn < a)
          break;
        if (A[nn] < 0)
          fb = false;
        if (fa && A[nn] >= 0)
          sumA += A[nn];
        nn--;
        mm--;
      }
    } else {
      while (1) {
        if (nn < a)
          break;
        if (A[nn] < 0)
          fb = false;
        if (fa && A[nn] >= 0)
          sumA += A[nn];
        if (mm < b)
          break;
        if (B[mm] < 0)
          fa = false;
        if (fb && B[mm] >= 0)
          sumB += B[mm];
        nn--;
        mm--;
      }
    }
    return sumA - sumB;
  }
  if (dp[n][m][a][b][t][con] != -INF)
    return dp[n][m][a][b][t][con];

  int ret;
  if (!t) { // player1
    ret = -INF;
    if (n < N)
      ret = max(ret, dfs(n + 1, m, a, b, !t, 0));
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    while (1) {
      if (mm < b)
        break;
      if (B[mm] < 0)
        fa = false;
      if (fb && B[mm] >= 0)
        sumB += B[mm];
      if (nn < a)
        break;
      if (A[nn] < 0)
        fb = false;
      if (fa && A[nn] >= 0)
        sumA += A[nn];
      nn--;
      mm--;
    }
    if (sumA || sumB)
      ret = max(ret, dfs(n, m, n, m, !t, 0) + sumA - sumB);
    else {
      ret = max(ret, dfs(n, m, n, m, !t, con + 1) + sumA - sumB);
    }
  } else { // player2
    ret = INF;
    if (m < M)
      ret = min(ret, dfs(n, m + 1, a, b, !t, 0));
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    while (1) {
      if (nn < a)
        break;
      if (A[nn] < 0)
        fb = false;
      if (fa && A[nn] >= 0)
        sumA += A[nn];
      if (mm < b)
        break;
      if (B[mm] < 0)
        fa = false;
      if (fb && B[mm] >= 0)
        sumB += B[mm];
      nn--;
      mm--;
    }
    if (sumA || sumB)
      ret = min(ret, dfs(n, m, n, m, !t, 0) + sumA - sumB);
    else {
      ret = min(ret, dfs(n, m, n, m, !t, con + 1) + sumA - sumB);
    }
  }

  return dp[n][m][a][b][t][con] = ret;
}

signed main() {
  cin >> N >> M;

  A = vector<int>(N);
  B = vector<int>(M);
  for (int i = 0; i < N; i++)
    cin >> A[i];
  for (int i = 0; i < M; i++)
    cin >> B[i];

  fill_n(*****dp, 51 * 51 * 51 * 51 * 2 * 3, -INF);
  cout << dfs(0, 0, 0, 0, 0, 0) << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int INF = 1e9;

int N, M;
vector<int> A, B;
int dp[51][51][51][51][2][3];

int dfs(int n, int m, int a, int b, int t, int con) {
  if (con == 2)
    return 0;
  if (n == N && m == M) {
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    if (!t) {
      while (1) {
        if (mm < b)
          break;
        if (B[mm] < 0)
          fa = false;
        if (fb && B[mm] >= 0)
          sumB += B[mm];
        if (nn < a)
          break;
        if (A[nn] < 0)
          fb = false;
        if (fa && A[nn] >= 0)
          sumA += A[nn];
        nn--;
        mm--;
      }
    } else {
      while (1) {
        if (nn < a)
          break;
        if (A[nn] < 0)
          fb = false;
        if (fa && A[nn] >= 0)
          sumA += A[nn];
        if (mm < b)
          break;
        if (B[mm] < 0)
          fa = false;
        if (fb && B[mm] >= 0)
          sumB += B[mm];
        nn--;
        mm--;
      }
    }
    return sumA - sumB;
  }
  if (dp[n][m][a][b][t][con] >= 0)
    return dp[n][m][a][b][t][con];

  int ret;
  if (!t) { // player1
    ret = -INF;
    if (n < N)
      ret = max(ret, dfs(n + 1, m, a, b, !t, 0));
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    while (1) {
      if (mm < b)
        break;
      if (B[mm] < 0)
        fa = false;
      if (fb && B[mm] >= 0)
        sumB += B[mm];
      if (nn < a)
        break;
      if (A[nn] < 0)
        fb = false;
      if (fa && A[nn] >= 0)
        sumA += A[nn];
      nn--;
      mm--;
    }
    if (sumA || sumB)
      ret = max(ret, dfs(n, m, n, m, !t, 0) + sumA - sumB);
    else {
      ret = max(ret, dfs(n, m, n, m, !t, con + 1) + sumA - sumB);
    }
  } else { // player2
    ret = INF;
    if (m < M)
      ret = min(ret, dfs(n, m + 1, a, b, !t, 0));
    int nn = n - 1;
    int mm = m - 1;
    bool fa = true, fb = true;
    int sumA = 0, sumB = 0;
    while (1) {
      if (nn < a)
        break;
      if (A[nn] < 0)
        fb = false;
      if (fa && A[nn] >= 0)
        sumA += A[nn];
      if (mm < b)
        break;
      if (B[mm] < 0)
        fa = false;
      if (fb && B[mm] >= 0)
        sumB += B[mm];
      nn--;
      mm--;
    }
    if (sumA || sumB)
      ret = min(ret, dfs(n, m, n, m, !t, 0) + sumA - sumB);
    else {
      ret = min(ret, dfs(n, m, n, m, !t, con + 1) + sumA - sumB);
    }
  }

  return dp[n][m][a][b][t][con] = ret;
}

signed main() {
  cin >> N >> M;

  A = vector<int>(N);
  B = vector<int>(M);
  for (int i = 0; i < N; i++)
    cin >> A[i];
  for (int i = 0; i < M; i++)
    cin >> B[i];

  fill_n(*****dp, 51 * 51 * 51 * 51 * 2 * 3, -1);
  cout << dfs(0, 0, 0, 0, 0, 0) << endl;

  return 0;
}