- f[i][l] 表示前i个元素,选l个,且当前位置选的最大值。
- f[i][l]从f[j][l - 1]转移, i - k <= j < i,用单调队列优化
- 不能有f[i][l] <-- f[i- 1][l] 这样没法控制每k个选一个
- 所以初始还要把f赋-1,f[0][0] = 0
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
//#define int long long
const int N = 3e3 + 5;
const int M = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
const double PI = acos(-1.0);
ll a[N], n, k;
ll f[N][N];
int hh[N], tt[N], q[N][N];
ll que( int i, int l) {
//int de1 = hh[l], de2 = tt[l];
while( hh[l] <= tt[l] && f[q[tt[l]][l]][l] <= f[i][l] ) -- tt[l];
//de1 = hh[l], de2 = tt[l];
q[++tt[l]][l] = i;
//de1 = hh[l], de2 = tt[l];
while( hh[l] <= tt[l] && q[hh[l]][l] < i + 1 - k ) ++ hh[l];
//de1 = hh[l], de2 = tt[l];
return f[q[hh[l]][l]][l];
}
int main () {
IOS
memset ( tt, -1, sizeof tt );
memset ( f, -1, sizeof f );
int x; cin >> n >> k >> x;
// if( x < n / k ) {
// cout << -1 << '\n'; return 0;
// }
f[0][0] = 0;
for ( int i = 1; i <= n; ++ i ) cin >> a[i];
for ( int i = 1; i <= n; ++ i ) {
for ( int l = 1; l <= min(x, i); ++ l ) {
ll de = que(i - 1, l - 1);
ll tmp = de >= 0 ? de + a[i] : -1;
f[i][l] = tmp;
}
}
ll ans = -1;
for ( int i = n - k + 1; i <= n; ++ i ) {
ans = max( ans, f[i][x]);
}
cout << ans << '\n';
return 0;
}