Problem p03161 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>  //sort,二分探索,など
#include <bitset>     //固定長bit集合
#include <cmath>      //pow,logなど
#include <complex>    //複素数
#include <deque>      //両端アクセスのキュー
#include <functional> //sortのgreater
#include <iomanip>    //setprecision(浮動小数点の出力の誤差)
#include <iostream>   //入出力
#include <map>        //map(辞書)
#include <numeric>    //iota(整数列の生成),gcdとlcm(c++17)
#include <queue>      //キュー
#include <set>        //集合
#include <stack>      //スタック
#include <stdio.h>
#include <string>        //文字列
#include <unordered_map> //イテレータあるけど順序保持しないmap
#include <unordered_set> //イテレータあるけど順序保持しないset
#include <utility>       //pair
#include <vector>        //可変長配列

using namespace std;
typedef long long ll;

// マクロ
#define REP(i, n) for (ll i = 0; i < (ll)(n); i++)
#define REPD(i, n) for (ll i = (ll)(n)-1; i >= 0; i--)
#define FOR(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORD(i, a, b) for (ll i = (a); i >= (b); i--)
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#define SIZE(x) ((ll)(x).size())      // sizeをsize_tからllに直しておく
#define MAX(x) *max_element(ALL(x))
#define INF 1000000000000 // 10^12
#define MOD 10000007      // 10^9+7
#define PB push_back
#define MP make_pair

int N;
int h[100000];
int K;
int dp[1000000];

int rec(int p) {
  int ans = 1000000;
  int sub[K];
  if (dp[p] >= 0) {
    ans = dp[p];
  }
  if (p == N - 1) {
    ans = 0;
  } else {
    REP(i, K) {
      if (p + i + 1 > N - 1) {
        sub[i] = 1000000;
      } else {
        sub[i] = rec(p + i + 1) + abs(h[p] - h[p + i + 1]);
      }
    }

    ans = sub[0];
    REP(i, K) {
      if (sub[i] < ans) {
        ans = sub[i];
      }
    }
  }
  dp[p] = ans;
  return ans;
}

int solve() {
  scanf("%d %d", &N, &K);

  REP(i, N) {
    scanf("%d", &h[i]);
    dp[i] = -1;
  }
  printf("%d", rec(0));

  return 0;
}

int main() { solve(); }

Fixed submission:
#include <algorithm>  //sort,二分探索,など
#include <bitset>     //固定長bit集合
#include <cmath>      //pow,logなど
#include <complex>    //複素数
#include <deque>      //両端アクセスのキュー
#include <functional> //sortのgreater
#include <iomanip>    //setprecision(浮動小数点の出力の誤差)
#include <iostream>   //入出力
#include <map>        //map(辞書)
#include <numeric>    //iota(整数列の生成),gcdとlcm(c++17)
#include <queue>      //キュー
#include <set>        //集合
#include <stack>      //スタック
#include <stdio.h>
#include <string>        //文字列
#include <unordered_map> //イテレータあるけど順序保持しないmap
#include <unordered_set> //イテレータあるけど順序保持しないset
#include <utility>       //pair
#include <vector>        //可変長配列

using namespace std;
typedef long long ll;

// マクロ
#define REP(i, n) for (ll i = 0; i < (ll)(n); i++)
#define REPD(i, n) for (ll i = (ll)(n)-1; i >= 0; i--)
#define FOR(i, a, b) for (ll i = (a); i <= (b); i++)
#define FORD(i, a, b) for (ll i = (a); i >= (b); i--)
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#define SIZE(x) ((ll)(x).size())      // sizeをsize_tからllに直しておく
#define MAX(x) *max_element(ALL(x))
#define INF 1000000000000 // 10^12
#define MOD 10000007      // 10^9+7
#define PB push_back
#define MP make_pair

int N;
int h[100000];
int K;
int dp[1000000];

int rec(int p) {
  int ans = 1000000;
  int sub[K];
  if (dp[p] >= 0) {
    ans = dp[p];
  } else if (p == N - 1) {
    ans = 0;
  } else {
    REP(i, K) {
      if (p + i + 1 > N - 1) {
        sub[i] = 1000000;
      } else {
        sub[i] = rec(p + i + 1) + abs(h[p] - h[p + i + 1]);
      }
    }

    ans = sub[0];
    REP(i, K) {
      if (sub[i] < ans) {
        ans = sub[i];
      }
    }
  }
  dp[p] = ans;
  return ans;
}

int solve() {
  scanf("%d %d", &N, &K);

  REP(i, N) {
    scanf("%d", &h[i]);
    dp[i] = -1;
  }
  printf("%d", rec(0));

  return 0;
}

int main() { solve(); }