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

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <queue>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

inline int getInt() {
  int s;
  scanf("%d", &s);
  return s;
}

using namespace std;

int main() {
  while (true) {
    int n = getInt();
    int m = getInt();

    if (n + m == 0)
      break;

    vector<map<int, int>> v(n);

    REP(i, n) {
      const int k = getInt();
      REP(j, k) {
        const int x = getInt();
        const int d = getInt();
        v[i][x] = d;
      }
    }

    vector<vector<map<int, int>>> dp(n, vector<map<int, int>>(m + 1));

    FOR(it, v[0]) { dp[0][m][it->first] = 0; }

    if (m > 0) {
      FOR(it, v[1]) { dp[1][m - 1][it->first] = 0; }
    }

    REP(i, n - 1) REP(j, m + 1) FOR(it1, dp[i][j]) {
      // printf("(%d, %d) %d => %d\\n", it1->first, i, j, it1->second);

      FOR(it2, v[i + 1]) {
        const int x1 = it1->first;
        const int x2 = it2->first;
        const int cost = (v[i][it1->first] + it2->second) * std::abs(x1 - x2);
        const int next = it1->second + cost;

        // printf(" (%d, %d) %d: %d\\n", x2, i + 1, j, next);

        if (dp[i + 1][j].count(x2))
          dp[i + 1][j][x2] = min(dp[i + 1][j][x2], next);
        else
          dp[i + 1][j][x2] = next;
      }
      if (j != 0 && i != n - 2) {
        FOR(it2, v[i + 2]) {
          const int x1 = it1->first;
          const int x2 = it2->first;
          const int cost = (v[i][it1->first] + it2->second) * std::abs(x1 - x2);
          const int next = it1->second + cost;

          // printf(" (%d, %d) %d: %d\\n", x2, i + 2, j - 1, next);

          if (dp[i + 2][j - 1].count(x2))
            dp[i + 2][j - 1][x2] = min(dp[i + 2][j - 1][x2], next);
          else
            dp[i + 2][j - 1][x2] = next;
        }
      }
    }

    int ans = INT_MAX;

    REP(j, m + 1) FOR(it, dp[n - 1][j]) { ans = min(ans, it->second); }
    REP(j, m) FOR(it, dp[n - 2][j + 1]) { ans = min(ans, it->second); }

    printf("%d\\n", ans);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\\n", x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

int memo[80][150][1001];

int main() {
  int n, m;
  while (n = getInt(), m = getInt(), n + m) {
    vector<vector<pair<int, int>>> stone(n);
    memset(memo, -1, sizeof(memo));
    REP(i, n) {
      int num = getInt();
      stone[i] = vector<pair<int, int>>(num);
      REP(j, num) {
        stone[i][j].f = getInt();
        stone[i][j].s = getInt();
      }
    }

    FOR(it, stone[0]) memo[m][0][it->f] = 0;
    if (m != 0)
      FOR(it, stone[1]) memo[m - 1][1][it->f] = 0;

    REP(i, n - 1) {
      FOR(it, stone[i]) {
        int j = it->f;
        int s = it->s;
        REP(k, m + 1) {
          if (memo[k][i][j] != -1) {
            FOR(it2, stone[i + 1]) {
              int jj = it2->f;
              int ss = it2->s;
              int mm = memo[k][i][j];

              if (memo[k][i + 1][jj] == -1)
                memo[k][i + 1][jj] = mm + (s + ss) * abs(j - jj);
              else
                memo[k][i + 1][jj] =
                    min(memo[k][i + 1][jj], mm + (s + ss) * abs(j - jj));
            }

            if (k != 0 && i != n - 2) {
              FOR(it2, stone[i + 2]) {
                int jj = it2->f;
                int ss = it2->s;
                int mm = memo[k][i][j];

                if (memo[k - 1][i + 2][jj] == -1)
                  memo[k - 1][i + 2][jj] = mm + (s + ss) * abs(j - jj);
                else
                  memo[k - 1][i + 2][jj] =
                      min(memo[k][i + 2][jj], mm + (s + ss) * abs(j - jj));
              }
            }
          }
        }
      }
    }

    // puts("0:"); REP(i,n) { REP(j,n) printf("%2d ",memo[0][i][j]); puts(""); }
    // puts("1:"); REP(i,n) { REP(j,n) printf("%2d ",memo[1][i][j]); puts(""); }

    int ans = INT_MAX;
    REP(j, n) REP(k, m + 1) {
      if (memo[k][n - 1][j] != -1)
        ans = min(ans, memo[k][n - 1][j]);
      if (k != 0) {
        if (memo[k][n - 2][j] != -1)
          ans = min(ans, memo[k][n - 2][j]);
      }
    }

    print(ans);
  }
  return 0;
}