题意
给定一个长度为 \(n\) 的整数序列 \(a_1, a_2, \dots, a_n\)。
请你从中挑选 \(x\) 个元素,要求:
- 原序列中的每一个长度为 \(k\) 的连续子序列都至少包含一个被选中的元素。
输出最大可能和。
数据范围
\(1 \leq n, k, x \leq 200\)
思路
考虑使用DP。令\(f_{i, j}\)表示最后一个选取的元素的下标是\(i\),总共选取了\(j\)个元素的最大和。则:
\(f_{i, j} = \max\limits_{i - k \leq t < i}(f_{i, j}, f_{t, j - 1})\)。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 210;
int n, kk, x;
ll a[N];
ll f[N][N];
int main()
{
scanf("%d%d%d", &n, &kk, &x);
for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
memset(f, -0x3f, sizeof f);
f[0][0] = 0;
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= x; j ++) {
for(int k = max(0, i - kk); k < i; k ++) {
f[i][j] = max(f[i][j], f[k][j - 1] + a[i]);
}
}
}
ll ans = -1;
for(int i = n - kk + 1; i <= n; i ++) ans = max(f[i][x], ans);
printf("%lld\n", ans);
return 0;
}