Problem p00548 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 99999999999999

int N, M;
ll K;

ll *table, *memo;

ll recursive(int index) {

  if (index >= N)
    return 0;

  if (memo[index] != -1)
    return memo[index];

  ll ret = NUM;
  ll max_orange = -1, min_orange = NUM;

  for (int i = 1; i <= M; i++) {
    if (index + i > N)
      continue;
    max_orange = max(max_orange, table[index + i - 1]);
    min_orange = min(min_orange, table[index + i - 1]);
    ret = min(ret, recursive(index + i) + i * (max_orange - min_orange) + K);
  }

  return memo[index] = ret;
}

int main() {
  scanf("%d %d %lld", &N, &M, &K);
  table = new ll[N];
  memo = new ll[N];
  for (int i = 0; i < N; i++)
    memo[i] = -1;

  for (int i = 0; i < N; i++)
    scanf("%lld", &table[i]);

  printf("%lld\\n", recursive(0));

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 99999999999999

ll *memo;

enum Type {
  max_value,
  min_value,
};

struct RMQ {
  void set(ll arg_minimum, ll arg_maximum) {
    minimum = arg_minimum;
    maximum = arg_maximum;
  }
  ll minimum, maximum;
};

int N = 1;
RMQ *Tree;

void init(int first_N) {
  while (N < first_N)
    N *= 2;
}

void update(int index, ll orange) {

  index += N - 1;

  Tree[index].minimum = min(Tree[index].minimum, orange);
  Tree[index].maximum = max(Tree[index].maximum, orange);

  index = (index - 1) / 2;

  while (true) {

    Tree[index].minimum =
        min(Tree[2 * index + 1].minimum, Tree[2 * index + 2].minimum);
    Tree[index].maximum =
        max(Tree[2 * index + 1].maximum, Tree[2 * index + 2].maximum);

    if (index == 0)
      break;
    else {
      index = (index - 1) / 2;
    }
  }
}

ll find(int search_left, int search_right, int node_id, int node_left,
        int node_right, Type type) {

  if (search_right < node_left || search_left > node_right) {
    if (type == max_value) {
      return -1;
    } else { // type == min_value;
      return NUM;
    }
  }

  if (search_left <= node_left && search_right >= node_right) {
    if (type == max_value) {
      return Tree[node_id].maximum;
    } else {
      return Tree[node_id].minimum;
    }
  }

  if (type == min_value) {
    ll left_min = find(search_left, search_right, 2 * node_id + 1, node_left,
                       (node_left + node_right) / 2, type);
    ll right_min = find(search_left, search_right, 2 * node_id + 2,
                        (node_left + node_right) / 2 + 1, node_right, type);

    return min(left_min, right_min);
  } else { // type == max_value
    ll left_max = find(search_left, search_right, 2 * node_id + 1, node_left,
                       (node_left + node_right) / 2, type);
    ll right_max = find(search_left, search_right, 2 * node_id + 2,
                        (node_left + node_right) / 2 + 1, node_right, type);

    return max(left_max, right_max);
  }
}

ll box_Cost;
int first_N, contain_Max;

ll recursive(int left) {

  if (left >= first_N)
    return 0;

  if (memo[left] != -1) {
    return memo[left];
  } else {

    ll ret = NUM;
    ll min_orange, max_orange;

    for (int i = 1; i <= contain_Max; i++) {
      if (left + i > first_N)
        continue;

      min_orange = find(left, min(N - 1, left + i - 1), 0, 0, N - 1, min_value);
      max_orange = find(left, min(N - 1, left + i - 1), 0, 0, N - 1, max_value);
      ret = min(ret,
                recursive(left + i) + i * (max_orange - min_orange) + box_Cost);
    }
    return memo[left] = ret;
  }
}

int main() {

  scanf("%d %d %lld", &first_N, &contain_Max, &box_Cost);

  init(first_N);

  memo = new ll[first_N];
  for (int i = 0; i < first_N; i++) {
    memo[i] = -1;
  }

  Tree = (RMQ *)malloc(sizeof(RMQ) * (2 * N));

  for (int i = 0; i < 2 * N - 1; i++) {
    Tree[i].set(NUM, -1);
  }

  ll tmp;
  for (int i = 0; i < first_N; i++) {
    scanf("%lld", &tmp);
    update(i, tmp);
  }

  printf("%lld\\n", recursive(0));

  return 0;
}