Problem p03161 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define INF (int)(1e9)

// Relevant constraints
// 2 <= N <= 10^5
// 1 <= K <= 100
// 2 secs

// Generalized version of frog1
// to K possible steps instead of 2
// Naturally, this turns the complexity
// required from O(n) to O(nK)
// This is acceptable for our constraints

// Recurrence to optimize:
// c(n) = min({c(n - 1) + cost(n, n - 1), c(n - 2) + cost(n, n - 2), ...,
//             c(n - k) + cost(n, n - k)})

// It doesn't matter how we use K in the future
// so that parameter is irrelevant for larger values
// and doesn't need to be stored
unordered_map<int, int> map_dp;
int solve_memo(const vector<int> &h, int n, int k) {
  if (n < 0)
    return INF;
  if (n == 0)
    return 0;
  if (map_dp.find(n) != map_dp.end())
    return map_dp[n];

  int min_n = INF;
  for (int i = 1; i <= k; ++i) {
    min_n = min(min_n, solve_memo(h, n - i, k) + abs(h[n] - h[n - i]));
  }

  return map_dp[n] = min_n;
}

int solve_tab(const vector<int> &h, int n, int k) {
  vector<int> dp(n);

  // Initial conditions
  dp[0] = 0;
  dp[1] = abs(h[0] - h[1]);

  for (int i = 2; i < n; ++i) {
    int min_n = INF;
    for (int j = 1; j <= k; ++j) {
      if (i - j < 0)
        break;

      min_n = min(min_n, dp[i - j] + abs(h[i] - h[i - j]));
    }
    dp[i] = min_n;
  }

  // dp[n - 1] represents the minimum cost
  // to get to stone n
  // in general dp[i] represents the minimum
  // cost to get to stone i
  return dp[n - 1];
}

int main() {

  cin.tie(NULL);
  ios_base::sync_with_stdio(false);

  int n, k;
  cin >> n >> k;

  vector<int> h(n);
  for (int i = 0; i < n; ++i) {
    cin >> h[i];
  }

  // n - 1 to accomodate the array size
  cout << solve_memo(h, n - 1, k) << '\n';
  // cout << solve_tab(h, n, k) << '\n';

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define INF (int)(1e9)

// Relevant constraints
// 2 <= N <= 10^5
// 1 <= K <= 100
// 2 secs

// Generalized version of frog1
// to K possible steps instead of 2
// Naturally, this turns the complexity
// required from O(n) to O(nK)
// This is acceptable for our constraints

// Recurrence to optimize:
// c(n) = min({c(n - 1) + cost(n, n - 1), c(n - 2) + cost(n, n - 2), ...,
//             c(n - k) + cost(n, n - k)})

// It doesn't matter how we use K in the future
// so that parameter is irrelevant for larger values
// and doesn't need to be stored
unordered_map<int, int> map_dp;
int solve_memo(const vector<int> &h, int n, int k) {
  if (n < 0)
    return INF;
  if (n == 0)
    return 0;
  if (map_dp.find(n) != map_dp.end())
    return map_dp[n];

  int min_n = INF;
  for (int i = 1; i <= k; ++i) {
    if (n - i < 0)
      continue;

    min_n = min(min_n, solve_memo(h, n - i, k) + abs(h[n] - h[n - i]));
  }

  return map_dp[n] = min_n;
}

int solve_tab(const vector<int> &h, int n, int k) {
  vector<int> dp(n);

  // Initial conditions
  dp[0] = 0;
  dp[1] = abs(h[0] - h[1]);

  for (int i = 2; i < n; ++i) {
    int min_n = INF;
    for (int j = 1; j <= k; ++j) {
      if (i - j < 0)
        break;

      min_n = min(min_n, dp[i - j] + abs(h[i] - h[i - j]));
    }
    dp[i] = min_n;
  }

  // dp[n - 1] represents the minimum cost
  // to get to stone n
  // in general dp[i] represents the minimum
  // cost to get to stone i
  return dp[n - 1];
}

int main() {

  cin.tie(NULL);
  ios_base::sync_with_stdio(false);

  int n, k;
  cin >> n >> k;

  vector<int> h(n);
  for (int i = 0; i < n; ++i) {
    cin >> h[i];
  }

  // n - 1 to accomodate the array size
  cout << solve_memo(h, n - 1, k) << '\n';
  // cout << solve_tab(h, n, k) << '\n';

  return 0;
}