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

#include <algorithm>
#include <iostream>

using namespace std;

const int INF = (1 << 15) - 2;
const int MAX = 100001;
const int FOOT = 10;
short dp[MAX][FOOT][FOOT][2];
string s;

int getColumn(int num) {
  int step[3][3] = {{7, 8, 9}, {4, 5, 6}, {1, 2, 3}};

  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (step[i][j] == num)
        return j;
}

void init() {
  fill(dp[0][0][0], dp[0][0][0] + MAX * FOOT * FOOT * 2, INF);
  for (int i = 0; i < FOOT; i++)
    for (int j = i; j < FOOT; j++)
      dp[0][i][j][0] = dp[0][i][j][1] = 0;
}

void solve() {

  short ans = INF;

  for (int i = 0; i < (int)s.length(); i++) {
    int pos = s[i] - '0';

    for (int l = 1; l < FOOT; l++) {
      if (l == 5)
        continue;
      for (int r = 1; r < FOOT; r++) {
        if (r == 5)
          continue;
        for (int x = 0; x < 2; x++) {
          // x = 0 -> left 1 -> right
          if (x) {
            // follow the rule(right foot)
            if (getColumn(l) <= getColumn(pos))
              dp[i + 1][l][pos][1] = min(dp[i + 1][l][pos][1], dp[i][l][r][0]);
            // violate(left foot)
            if (getColumn(r) >= getColumn(pos))
              dp[i + 1][pos][r][0] =
                  min(dp[i + 1][pos][r][0], (short)(dp[i][l][r][0] + 1));
          } else {
            // follow the rule(left foot)
            if (getColumn(r) >= getColumn(pos))
              dp[i + 1][pos][r][0] = min(dp[i + 1][pos][r][0], dp[i][l][r][1]);
            // violate(right foot)
            if (getColumn(l) <= getColumn(pos))
              dp[i + 1][l][pos][1] =
                  min(dp[i + 1][l][pos][1], (short)(dp[i][l][r][1] + 1));
          }
        }
      }
    }
    for (int i = 1; i < FOOT; i++)
      for (int j = 1; j < FOOT; j++)
        ans = min(ans, min(dp[s.length()][i][j][0], dp[s.length()][i][j][1]));
  }
  cout << ans << endl;
}

int main() {
  while (cin >> s && s != "#") {
    init();
    solve();
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>

using namespace std;

const int INF = (1 << 25);
const int MAX = 100001;
const int FOOT = 10;
int dp[MAX][FOOT][FOOT][2];
string s;

int getColumn(int num) {
  int step[3][3] = {{7, 8, 9}, {4, 5, 6}, {1, 2, 3}};

  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (step[i][j] == num)
        return j;
}

void init() {
  fill(dp[0][0][0], dp[0][0][0] + MAX * FOOT * FOOT * 2, INF);
  for (int i = 0; i < FOOT; i++)
    for (int j = i; j < FOOT; j++)
      dp[0][i][j][0] = dp[0][i][j][1] = 0;
}

void solve() {

  int ans = INF;

  for (int i = 0; i < s.length(); i++) {
    int pos = s[i] - '0';

    for (int l = 1; l < FOOT; l++) {
      if (l == 5)
        continue;
      for (int r = 1; r < FOOT; r++) {
        if (r == 5)
          continue;
        for (int x = 0; x < 2; x++) {
          // x = 0 -> left 1 -> right
          if (x) {
            // follow the rule(right foot)
            if (getColumn(l) <= getColumn(pos))
              dp[i + 1][l][pos][1] = min(dp[i + 1][l][pos][1], dp[i][l][r][0]);
            // violate(left foot)
            if (getColumn(r) >= getColumn(pos))
              dp[i + 1][pos][r][0] =
                  min(dp[i + 1][pos][r][0], dp[i][l][r][0] + 1);
          } else {
            // follow the rule(left foot)
            if (getColumn(r) >= getColumn(pos))
              dp[i + 1][pos][r][0] = min(dp[i + 1][pos][r][0], dp[i][l][r][1]);
            // violate(right foot)
            if (getColumn(l) <= getColumn(pos))
              dp[i + 1][l][pos][1] =
                  min(dp[i + 1][l][pos][1], dp[i][l][r][1] + 1);
          }
        }
      }
    }
    for (int i = 1; i < FOOT; i++)
      for (int j = 1; j < FOOT; j++)
        ans = min(ans, min(dp[s.length()][i][j][0], dp[s.length()][i][j][1]));
  }
  cout << ans << endl;
}

int main() {
  while (cin >> s && s != "#") {
    init();
    solve();
  }
  return 0;
}