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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

enum Type {
  Sente,
  Gote,
};

int dp[51][51][51][51][2][3];
int num_sente, num_gote;
int sente_array[51], gote_array[51];

int calc(int sente_0, int sente_1, int gote_0, int gote_1, int pass_num,
         Type turn, int sente_value, int gote_value) {

  //?¨???????????????????????????????
  if (abs(dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num]) != BIG_NUM) {
    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num];
  }

  int ret;

  if (turn == Sente) {

    ret = -BIG_NUM;

    if (sente_1 + 1 <= num_sente) {
      if (sente_array[sente_1 + 1] == -1) {
        ret = max(ret, calc(sente_0, sente_1 + 1, gote_0, gote_1, 0, Gote,
                            sente_value, 0));
      } else {
        ret =
            max(ret, calc(sente_0, sente_1 + 1, gote_0, gote_1, 0, Gote,
                          sente_value + sente_array[sente_1 + 1], gote_value));
      }
    }

    if (sente_0 == sente_1 && gote_0 == gote_1) {
      if (pass_num == 0) {
        ret = max(ret, calc(sente_1, sente_1, gote_1, gote_1, 1, Gote, 0, 0));
      } else { // pass_num == 1
        ret = max(ret, 0);
      }
    } else {
      ret = max(ret, sente_value - gote_value +
                         calc(sente_1, sente_1, gote_1, gote_1, 0, Gote, 0, 0));
    }

    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num] = ret;

  } else {

    ret = BIG_NUM;

    if (gote_1 + 1 <= num_gote) {
      if (gote_array[gote_1 + 1] == -1) {
        ret = min(ret, calc(sente_0, sente_1, gote_0, gote_1 + 1, 0, Sente, 0,
                            gote_value));
      } else {
        ret = min(ret, calc(sente_0, sente_1, gote_0, gote_1 + 1, 0, Sente,
                            sente_value, gote_value + gote_array[gote_1 + 1]));
      }
    }

    if (sente_0 == sente_1 && gote_0 == gote_1) {
      if (pass_num == 0) {
        ret = min(ret, calc(sente_1, sente_1, gote_1, gote_1, pass_num + 1,
                            Sente, 0, 0));
      } else { // pass_num == 1
        ret = min(ret, 0);
      }
    } else {
      ret =
          min(ret, sente_value - gote_value +
                       calc(sente_1, sente_1, gote_1, gote_1, 0, Sente, 0, 0));
    }

    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num] = ret;
  }
}

int main() {

  for (int a = 0; a <= 50; a++) {
    for (int b = 0; b <= 50; b++) {
      for (int c = 0; c <= 50; c++) {
        for (int d = 0; d <= 50; d++) {
          for (int e = 0; e < 2; e++) {
            for (int f = 0; f < 2; f++) {
              if (e == 0) {
                dp[a][b][c][d][e][f] = -BIG_NUM;
              } else {
                dp[a][b][c][d][e][f] = BIG_NUM;
              }
            }
          }
        }
      }
    }
  }

  scanf("%d %d", &num_sente, &num_gote);
  for (int i = 1; i <= num_sente; i++)
    scanf("%d", &sente_array[i]);
  for (int i = 1; i <= num_gote; i++)
    scanf("%d", &gote_array[i]);

  printf("%d\\n", calc(0, 0, 0, 0, 0, Sente, 0, 0));

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

enum Type {
  Sente,
  Gote,
};

int ******dp;
int num_sente, num_gote;
int sente_array[51], gote_array[51];

int calc(short sente_0, short sente_1, short gote_0, short gote_1,
         short pass_num, Type turn, int sente_value, int gote_value) {

  //?¨???????????????????????????????
  if (abs(dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num]) != BIG_NUM) {
    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num];
  }

  int ret;

  if (turn == Sente) {

    ret = -BIG_NUM;

    if (sente_1 + 1 <= num_sente) {
      if (sente_array[sente_1 + 1] == -1) {
        ret = max(ret, calc(sente_0, sente_1 + 1, gote_0, gote_1, 0, Gote,
                            sente_value, 0));
      } else {
        ret =
            max(ret, calc(sente_0, sente_1 + 1, gote_0, gote_1, 0, Gote,
                          sente_value + sente_array[sente_1 + 1], gote_value));
      }
    }

    if (sente_0 == sente_1 && gote_0 == gote_1) {
      if (pass_num == 0) {
        ret = max(ret, calc(sente_1, sente_1, gote_1, gote_1, 1, Gote, 0, 0));
      } else { // pass_num == 1
        ret = max(ret, 0);
      }
    } else {
      ret = max(ret, sente_value - gote_value +
                         calc(sente_1, sente_1, gote_1, gote_1, 0, Gote, 0, 0));
    }

    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num] = ret;

  } else {

    ret = BIG_NUM;

    if (gote_1 + 1 <= num_gote) {
      if (gote_array[gote_1 + 1] == -1) {
        ret = min(ret, calc(sente_0, sente_1, gote_0, gote_1 + 1, 0, Sente, 0,
                            gote_value));
      } else {
        ret = min(ret, calc(sente_0, sente_1, gote_0, gote_1 + 1, 0, Sente,
                            sente_value, gote_value + gote_array[gote_1 + 1]));
      }
    }

    if (sente_0 == sente_1 && gote_0 == gote_1) {
      if (pass_num == 0) {
        ret = min(ret, calc(sente_1, sente_1, gote_1, gote_1, pass_num + 1,
                            Sente, 0, 0));
      } else { // pass_num == 1
        ret = min(ret, 0);
      }
    } else {
      ret =
          min(ret, sente_value - gote_value +
                       calc(sente_1, sente_1, gote_1, gote_1, 0, Sente, 0, 0));
    }

    return dp[sente_0][sente_1][gote_0][gote_1][turn][pass_num] = ret;
  }
}

int main() {

  dp = new int *****[51];
  for (int a = 0; a <= 50; a++) {
    dp[a] = new int ****[51];
    for (int b = 0; b <= 50; b++) {
      dp[a][b] = new int ***[51];
      for (int c = 0; c <= 50; c++) {
        dp[a][b][c] = new int **[51];
        for (int d = 0; d <= 50; d++) {
          dp[a][b][c][d] = new int *[2];
          for (int e = 0; e < 2; e++) {
            dp[a][b][c][d][e] = new int[2];
            for (int f = 0; f < 2; f++) {
              if (e == 0) {
                dp[a][b][c][d][e][f] = -BIG_NUM;
              } else {
                dp[a][b][c][d][e][f] = BIG_NUM;
              }
            }
          }
        }
      }
    }
  }

  scanf("%d %d", &num_sente, &num_gote);
  for (int i = 1; i <= num_sente; i++)
    scanf("%d", &sente_array[i]);
  for (int i = 1; i <= num_gote; i++)
    scanf("%d", &gote_array[i]);

  printf("%d\\n", calc(0, 0, 0, 0, 0, Sente, 0, 0));

  return 0;
}