Codeforces Round #521 (Div. 3): F. Pictures with Kittens(DP+单调队列)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/84189222

题意:

你有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;
}

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/84189222
今日推荐