链接:
https://ac.nowcoder.com/acm/contest/918/J
题意:
在Farmer John最喜欢的节日里,他想要给他的朋友们赠送一些礼物。由于他并不擅长包装礼物,他想要获得他的奶牛们的帮助。你可能能够想到,奶牛们本身也不是很擅长包装礼物,而Farmer John即将得到这一教训。
Farmer John的N头奶牛(1≤N≤10^4)排成一行,方便起见依次编号为1…N。奶牛i的包装礼物的技能水平为si。她们的技能水平可能参差不齐,所以FJ决定把她的奶牛们分成小组。每一组可以包含任意不超过K头的连续的奶牛(1≤K≤10^3),并且一头奶牛不能属于多于一个小组。由于奶牛们会互相学习,这一组中每一头奶牛的技能水平会变成这一组中水平最高的奶牛的技能水平。
请帮助FJ求出,在他合理地安排分组的情况下,可以达到的技能水平之和的最大值。
思路:
dp[i]表示从1-i再满足条件情况下的最大值。从第一个找到最后一个。
每次从当前位置找最多k个,令dp[i]取到最大,假设j是从i开始往前的某个位置。
dp[i] = max(dp[i], dp[i-(i-j+1)]+mmax*(i-j+1))。
mmax是从i到j中最大的值。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e4 + 10;
const int MOD = 1e9 + 7;
int n, m, k, t;
int a[MAXN];
int dp[MAXN];
int main()
{
//freopen("test.in", "r", stdin);
cin >> n >> k;
for (int i = 1;i <= n;i++)
cin >> a[i];
for (int i = 1;i <= n;i++)
{
int mmax = -1;
for (int j = i;j >= 1 && j > i-k;j--)
{
mmax = max(mmax, a[j]);
dp[i] = max(dp[i], dp[i-(i-j+1)]+mmax*(i-j+1));
}
}
cout << dp[n] << endl;
return 0;
}