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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAXLEN = 2000;

const int dxs[] = {0, -1, -1, 0};
const int dys[] = {0, -1, 0, -1};

/* typedef */

/* global variables */

int dp[MAXLEN + 1][MAXLEN + 1], prvs[MAXLEN + 1][MAXLEN + 1];

/* subroutines */

/* main */

int main() {
  string str;
  while (cin >> str) {
    int len = str.length();

    memset(dp, 0, sizeof(dp));
    memset(prvs, 0, sizeof(prvs));

    for (int i = 0; i < len; i++)
      for (int j = 0; j < len - i; j++) {
        if (str[i] == str[len - 1 - j]) {
          dp[i + 1][j + 1] = dp[i][j] + 1;
          prvs[i + 1][j + 1] = 1;
        } else if (dp[i][j + 1] >= dp[i + 1][j]) {
          dp[i + 1][j + 1] = dp[i][j + 1];
          prvs[i + 1][j + 1] = 2;
        } else {
          dp[i + 1][j + 1] = dp[i + 1][j];
          prvs[i + 1][j + 1] = 3;
        }
      }

    int maxdp = 0, si, sj;

    for (int i = 1; i <= len; i++) {
      int j = len + 1 - i;
      int dp0 = 2 * dp[i][j] - 1;
      if (maxdp < dp0) {
        maxdp = dp0;
        si = i, sj = j;
      }
    }

    for (int i = 1; i < len; i++) {
      int j = len - i;
      int dp0 = 2 * dp[i][j];
      if (str[i - 1] == str[len - j] && maxdp < dp0) {
        maxdp = dp0;
        si = i, sj = j;
      }
    }
    // printf("maxdp=%d, si=%d, sj=%d\\n", maxdp, si, sj);

    string ans;

    while (si > 0 && sj > 0) {
      int prv = prvs[si][sj];
      if (prv == 1) {
        string ss = str.substr(si - 1, 1);
        if (si + sj == len + 1)
          ans = ss;
        else
          ans = ss + ans + ss;
      }

      si += dxs[prv];
      sj += dys[prv];
    }

    cout << ans << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAXLEN = 2000;

/* typedef */

/* global variables */

string memo[MAXLEN][MAXLEN];

/* subroutines */

string rec(string &str, int i0, int i1) {
  if (memo[i0][i1] != "-")
    return memo[i0][i1];

  if (i0 + 1 == i1) {
    if (str[i0] == str[i1])
      memo[i0][i1] = str.substr(i0, 2);
    else
      memo[i0][i1] = "";
    return memo[i0][i1];
  }

  string maxstr, s;
  int j0, j1;

  for (j1 = i1; str[i0] != str[j1]; j1--)
    ;
  if (i0 + 1 < j1)
    s = str.substr(i0, 1) + rec(str, i0 + 1, j1 - 1) + str.substr(j1, 1);
  else if (i0 + 1 == j1)
    s = str.substr(i0, 2);
  else
    s = str.substr(i0, 1);

  if (maxstr.length() < s.length())
    maxstr = s;

  for (j0 = i0; str[j0] != str[i1]; j0++)
    ;
  if (j0 + 1 < i1)
    s = str.substr(j0, 1) + rec(str, j0 + 1, i1 - 1) + str.substr(i1, 1);
  else if (j0 + 1 == i1)
    s = str.substr(j0, 2);
  else
    s = str.substr(j0, 1);

  if (maxstr.length() < s.length())
    maxstr = s;

  s = rec(str, i0 + 1, i1 - 1);
  if (maxstr.length() < s.length())
    maxstr = s;

  return (memo[i0][i1] = maxstr);
}

/* main */

int main() {
  for (;;) {
    string str;
    cin >> str;
    if (cin.eof())
      break;

    int len = str.length();
    for (int i = 0; i < len; i++) {
      for (int j = 0; j < len; j++)
        memo[i][j] = "-";
      memo[i][i] = str.substr(i, 1);
    }

    cout << rec(str, 0, len - 1) << endl;
  }

  return 0;
}