#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vpii = vector<pii>;
using vi = vector<int>;
using vvi = vector<vi>;
using ll = long long;
using vll = vector<long long>;
template <class T>
using min_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
istream &operator>>(istream &, vector<T> &);
template <class T>
ostream &operator<<(ostream &, const vector<T> &);
template <class T, class U>
istream &operator>>(istream &, pair<T, U> &);
template <class T, class U>
ostream &operator<<(ostream &, const pair<T, U> &);
template <class T>
struct Inf {
  static constexpr T inf() {
    return std::numeric_limits<T>::has_infinity()
               ? std::numeric_limits<T>::infinty()
               : std::numeric_limits<T>::max();
  }
};
template <>
struct Inf<int> {
  static constexpr int inf() { return 0x3f3f3f3f; }
};
template <>
struct Inf<long long> {
  static constexpr long long inf() { return 0x3f3f3f3f3f3f3f3fLL; }
};
constexpr int INF = Inf<int>::inf();
constexpr ll BINF = Inf<ll>::inf();
template <class T>
struct Max {
  constexpr const T &operator()(const T &lhs, const T &rhs) {
    return max(lhs, rhs);
  }
};
template <class T, class Operation = Max<T>>
class SegmentTree {
 private:
  int n;
  std::vector<T> tree;
  Operation op;

 public:
  SegmentTree(const std::vector<T> &init) : n(init.size()), tree(init.size()) {
    for (const T &x : init) tree.push_back(x);
    for (int i = n - 1; i > 0; i--)
      tree[i] = op(tree[i << 1], tree[i << 1 | 1]);
  }
  void modify(int p, const T &val) {
    p += n;
    tree[p] = max(tree[p], val);
    for (; p >>= 1;) tree[p] = op(tree[p << 1], tree[p << 1 | 1]);
  }
  void lazyModify(int p, const T &val) {
    p += n;
    tree[p] = max(tree[p], val);
  }
  void lazyUpdate() {
    for (int i = n - 1; i > 0; i--)
      tree[i] = op(tree[i << 1], tree[i << 1 | 1]);
  }
  T query(int l, int r) {
    T resl = -BINF, resr = -BINF;
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) resl = op(resl, tree[l++]);
      if (r & 1) resr = op(tree[--r], resr);
    }
    return op(resl, resr);
  }
};
int solve() {
  int n, k, x;
  cin >> n >> k >> x;
  vll a(n);
  cin >> a;
  vll init(n, -BINF);
  vector<SegmentTree<ll>> dp(2, SegmentTree<ll>(init));
  for (int j = 1; j <= x; j++) {
    dp[j & 1] = SegmentTree<ll>(init);
    if (j == 1) {
      for (int i = 0; i < k; i++) dp[j & 1].lazyModify(i, a[i]);
    } else {
      for (int i = j - 1; i < n; i++)
        dp[j & 1].lazyModify(i, a[i] + dp[~j & 1].query(max(0, i - k), i - 1));
    }
    dp[j & 1].lazyUpdate();
  }
  ll ans = dp[x & 1].query(n - k, n - 1);
  cout << (ans < 0 ? -1 : ans) << endl;
  return 0;
}
int main() {
  ios::sync_with_stdio(0);
  solve();
  return 0;
}
template <class T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto it = v.begin(); it != v.end(); ++it) is >> *it;
  return is;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (auto it = v.begin(); it != v.end();)
    os << *it, os << " \n"[++it == v.end()];
  return os;
}
template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ' ' << p.second;
}
