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

#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

#define max 100001

string str;
/*
        dp[インデックス][最後に踏んだ足][左足の番号][右足の番号]
*/

int min(int p, int q) {
  if (p > q)
    return q;
  return p;
}

int main(void) {
  // FILE* fp_in = freopen("data.txt", "r", stdin);

  int dp[2][2][9][9];

  while (1) {
    str = "";
    cin >> str;
    if (str == "#")
      break;
    int arrow = str[0] - '1';

    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          for (int l = 0; l < 2; l++)
            dp[l][i][j][k] = 1 << 30;

    for (int j = 0; j < 9; j++) {
      dp[1][1][j][arrow] = 0;
      dp[1][0][arrow][j] = 0;
    }

    for (int i = 1; i < str.length(); i++) {
      arrow = str[i] - '1';

      for (int j = 0; j < 2; j++)
        for (int k = 0; k < 9; k++)
          for (int l = 0; l < 9; l++)
            dp[0][j][k][l] = dp[1][j][k][l];

      for (int j = 0; j < 2; j++)
        for (int k = 0; k < 9; k++)
          for (int l = 0; l < 9; l++)
            dp[1][j][k][l] = 1 << 30;

      // i-1番目と同じ足を出す
      // 左足
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 <= k % 3 && j != k && j % 3 <= k % 3 && arrow != k)
            dp[1][0][arrow][k] = min(dp[0][0][j][k] + 1, dp[1][0][arrow][k]);
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 >= j % 3 && j != k && j % 3 <= k % 3 && arrow != j)
            dp[1][1][j][arrow] = min(dp[0][1][j][k] + 1, dp[1][1][j][arrow]);
      // i-1番目と異なる足を出す
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 <= k % 3 && j != k && j % 3 <= k % 3 && arrow != k)
            dp[1][0][arrow][k] = min(dp[0][1][j][k], dp[1][0][arrow][k]);
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 >= j % 3 && j != k && j % 3 <= k % 3 && arrow != j)
            dp[1][1][j][arrow] = min(dp[0][0][j][k], dp[1][1][j][arrow]);
    }

    int min = 1 << 30;
    // cout << str << endl;

    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (dp[1][i][j][k] < 1 << 30) {
            if (min > dp[1][i][j][k])
              min = dp[1][i][j][k];
          }
    cout << min << endl;
  }

  // while(1){}
  return 0;
}

Error: MLE

Fixed submission:

#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

#define max 100001

string str;
/*
        dp[インデックス][最後に踏んだ足][左足の番号][右足の番号]
*/

int min(int p, int q) {
  if (p > q)
    return q;
  return p;
}

int main(void) {
  //	FILE* fp_in = freopen("data.txt", "r", stdin);

  vector<vector<vector<vector<int>>>> dp;
  vector<vector<vector<int>>> dpppp;
  vector<vector<int>> dppp;
  vector<int> dpp;
  dpp.resize(9, 0);
  dppp.resize(9, dpp);
  dpppp.resize(2, dppp);
  dp.resize(max, dpppp);

  while (1) {
    str = "";
    cin >> str;
    if (str == "#")
      break;
    int arrow = str[0] - '1';

    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          for (int l = 0; l < str.length(); l++)
            dp[l][i][j][k] = 1 << 30;

    for (int j = 0; j < 9; j++) {
      dp[0][1][j][arrow] = 0;
      dp[0][0][arrow][j] = 0;
    }

    for (int i = 1; i < str.length(); i++) {
      arrow = str[i] - '1';

      // i-1番目と同じ足を出す
      // 左足
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 <= k % 3 && j != k && j % 3 <= k % 3 && arrow != k)
            dp[i][0][arrow][k] =
                min(dp[i - 1][0][j][k] + 1, dp[i][0][arrow][k]);
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 >= j % 3 && j != k && j % 3 <= k % 3 && arrow != j)
            dp[i][1][j][arrow] =
                min(dp[i - 1][1][j][k] + 1, dp[i][1][j][arrow]);
      // i-1番目と異なる足を出す
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 <= k % 3 && j != k && j % 3 <= k % 3 && arrow != k)
            dp[i][0][arrow][k] = min(dp[i - 1][1][j][k], dp[i][0][arrow][k]);
      for (int j = 0; j < 9; j++)
        for (int k = 0; k < 9; k++)
          if (arrow % 3 >= j % 3 && j != k && j % 3 <= k % 3 && arrow != j)
            dp[i][1][j][arrow] = min(dp[i - 1][0][j][k], dp[i][1][j][arrow]);
    }

    int min = 1 << 30;
    // cout << str << endl;

    for (int l = 0; l < str.length(); l++) {
      for (int i = 0; i < 2; i++)
        for (int j = 0; j < 9; j++)
          for (int k = 0; k < 9; k++)
            if (dp[l][i][j][k] < 1 << 30) {
              //						cout <<
              //dp[l][i][j][k] << " " << l <<  " " << i << " " << j << " " << k
              //<< endl;
              if (min > dp[str.length() - 1][i][j][k])
                min = dp[str.length() - 1][i][j][k];
            }
      // cout << "+++++" << endl;
    }

    //
    //	cout<< "***" << endl;
    cout << min << endl;
  }

  //	while(1){}
  return 0;
}