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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 1200
#define P 188
#define N 1121
#define K 14

vector<int> vprimes;
bool *isPrime = new bool[MAX];

/* ツ素ツ青板青カツ青ャ O(n^2) */
void MakePrime() {
  isPrime[0] = false;
  isPrime[1] = false;
  isPrime[2] = true;
  for (int i = 2; i < MAX; ++i) {
    isPrime[i] = true;
  }
  for (long long int i = 2; i < MAX; ++i) {
    if (isPrime[i]) {
      for (long long int j = 2; i * j < MAX; ++j) {
        isPrime[i * j] = false;
      }
    }
  }
  for (int i = 0; i < MAX; ++i) {
    if (isPrime[i]) {
      vprimes.push_back(i);
    }
  }
}

int table[P][N][K];
int next_big_prime_index[N];

int solve(int last_prime, int n, int k) {
  int &t = table[last_prime][n][k];
  int ret = 0;
  if (k == 1) {
    if (isPrime[n] && n > vprimes[last_prime]) {
      t = 1;
      return 1;
    } else {
      t = 0;
      return 0;
    }
  } else {
    if (t != -1)
      return t;
    else {
      for (int i = last_prime + 1; vprimes[i] < MAX && n - vprimes[i] > 0;
           ++i) {
        ret += solve(i, n - vprimes[i], k - 1);
      }
      table[last_prime][n][k] = ret;
      return ret;
    }
  }
}

int main() {
  MakePrime();
  // cout << vprimes.size()  << endl;
  vprimes.insert(vprimes.begin(), 0);
  while (true) {
    int n, k;
    cin >> n >> k;
    fill(&table[0][0][0], &table[P - 1][N - 1][K - 1], -1);
    if (n == 0 && k == 0)
      break;
    cout << solve(0, n, k) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 2000
#define N 1121
#define K 14

vector<int> vprimes;
bool *isPrime = new bool[MAX];

/* ツ素ツ青板青カツ青ャ O(n^2) */
void MakePrime() {
  isPrime[0] = false;
  isPrime[1] = false;
  isPrime[2] = true;
  for (int i = 2; i < MAX; ++i) {
    isPrime[i] = true;
  }
  for (long long int i = 2; i < MAX; ++i) {
    if (isPrime[i]) {
      for (long long int j = 2; i * j < MAX; ++j) {
        isPrime[i * j] = false;
      }
    }
  }
  for (int i = 0; i < MAX; ++i) {
    if (isPrime[i]) {
      vprimes.push_back(i);
    }
  }
}

int table[N][N][K];
int next_big_prime_index[N];

int solve(int last_prime, int n, int k) {
  int &t = table[last_prime][n][k];
  int ret = 0;
  if (k == 1) {
    if (isPrime[n] && n > last_prime) {
      t = 1;
      return 1;
    } else {
      t = 0;
      return 0;
    }
  } else {
    if (t != -1)
      return t;
    else {
      for (int i = next_big_prime_index[last_prime];
           vprimes[i] < MAX && n - vprimes[i] > 0; ++i) {
        ret += solve(vprimes[i], n - vprimes[i], k - 1);
      }
      table[last_prime][n][k] = ret;
      return ret;
    }
  }
}

int main() {
  MakePrime();

  int ind = 0;
  for (int i = 0; i < N; ++i) {
    if (i < vprimes[ind]) {
      next_big_prime_index[i] = ind;
    } else {
      ++ind;
      --i;
    }
  }

  while (true) {
    int n, k;
    cin >> n >> k;
    fill(&table[0][0][0], &table[N - 1][N - 1][K - 1], -1);
    if (n == 0 && k == 0)
      break;
    cout << solve(1, n, k) << endl;
  }
  return 0;
}