[USACO18DEC]Teamwork(B题)

链接:coed force
中文链接:洛谷P5124

题目大意:

FJ想要给他的朋友送礼物,但是他不太会包装礼物,所以他把这个任务交给他的N(1<= N <= 104)奶牛们去完成。奶牛们排成一行依次编号为1…N,第i头奶牛的水平为si,它们的技能水平可能参差不齐,所以FJ打算给他的奶牛们分组,每一组可以有任意K(1<= K <= 103)头连续的奶牛,一头奶牛只能在一个组里面(可以自己一头牛一组)。由于奶牛们会互相学习,这一组中每一头奶牛的技能水平会变成这一组中水平最高的奶牛的技能水平。
请你求出最佳的分组方案下奶牛们可以达到技能之和的最大值。

数据大小:

如题意所示。

思路:

这题是一个dp题,设dp[i]表示当前水平之和的最大值。
有 :dp[i] = max(dp[j] + (i−j) ∗ max(a[j]))
其中 (max(0,i−k) ≤ j < i)(转移方程是dl推的%%%)
根据题目意思,每头奶牛可以自己成为一个组,也可以和连续的包括自己在内的不超过K头奶牛组成一组,假设k = 3,对于第i个奶牛,有
k = 1

k = 2
在这里插入图片描述
k = 3
在这里插入图片描述
但是对于i前面的来说,可以知道没有重复的部分是

在这里插入图片描述
对于每一个奶牛,我们只需要往后更新就行,不用理前面的部分,其组队的情况都包含在前面 i-k ~ i+k 个内了,只要每种情况最优就好了
其实我也还不太懂,讲的有点玄乎,见谅(lll¬ω¬)。
ac代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
#define MAX 10005
int dp[MAX];
int a[MAX];
int main()
{
	int n,k;
	scanf("%d %d",&n,&k);
	for(int i = 1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i = 1;i<=n;i++)
	{
		int temp_max = 0;
		for(int j = i;j<min(i+k,n+1);j++)//第i个数
		{
			if(a[j]>temp_max)
				temp_max = a[j];
			if(dp[j] < dp[i-1]+(j-i+1)*temp_max)//往后更新
				dp[j] = dp[i-1]+(j-i+1)*temp_max;
		}
	}
	printf("%d",dp[n]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值