题意:
你有n幅画,第i幅画的好看程度为ai,再给你两个数字k,x,表示你要从中选出刚好x幅画,并且相邻两幅画的距离不能≥k,好看程度之和最大能多少,选不出来输出-1,F1数据范围<200,F2数据范围<5000
注意相邻两幅画的距离不能≥k指的是中间没有选的画个数不能≥k,而不是绝对值之差≥k
思路:
dp[x][y]表示只考虑前y幅画,第y幅必选,且总共选了x幅画的最大好看程度
转移:dp[x][y] = max(dp[x-1][y-k]~dp[x-1][y-1])+a[y]
然后这个DP很明显可以用单调队列维护
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
LL a[5005], dp[2][5005];
int st[5005];
int main(void)
{
LL ans;
int n, k, m, i, p, R, L, now;
scanf("%d%d%d", &n, &m, &k);
for(i=1;i<=n;i++)
scanf("%lld", &a[i]);
memset(dp, -62, sizeof(dp));
dp[0][0] = 0, now = 1;
for(p=1;p<=k;p++)
{
L = 1, R = 0;
st[++R] = 0;
for(i=1;i<=n;i++)
{
while(R>=L && st[L]+m<i)
L++;
dp[now][i] = dp[now^1][st[L]]+a[i];
while(R>=L && dp[now^1][st[R]]<=dp[now^1][i])
R--;
st[++R] = i;
}
now ^= 1;
}
now ^= 1, ans = -1;
for(i=n;i>=n-m+1;i--)
ans = max(ans, dp[now][i]);
printf("%lld\n", ans);
return 0;
}