[USACO18DEC-Gold]Teamwork
题目描述
在Farmer John最喜欢的节日里,他想要给他的朋友们赠送一些礼物。由于他并不擅长包装礼物,他想要获得他的奶牛们的帮助。你可能能够想到,奶牛们本身也不是很擅长包装礼物,而Farmer John即将得到这一教训。 Farmer John的N头奶牛(1≤N≤104)排成一行,方便起见依次编号为1…N。奶牛i的包装礼物的技能水平为si。她们的技能水平可能参差不齐,所以FJ决定把她的奶牛们分成小组。每一组可以包含任意不超过K头的连续的奶牛(1≤K≤103),并且一头奶牛不能属于多于一个小组。由于奶牛们会互相学习,这一组中每一头奶牛的技能水平会变成这一组中水平最高的奶牛的技能水平。 请帮助FJ求出,在他合理地安排分组的情况下,可以达到的技能水平之和的最大值。
输入格式
输入的第一行包含N和K。以下N行按照N头奶牛的排列顺序依次给出她们的技能水平。技能水平是一个不超过105的正整数。
输出格式
输出FJ通过将连续的奶牛进行分组可以达到的最大技能水平和。
输入样例
7 3
1
15
7
9
2
5
10
输出样例
84
【样例说明】
在这个例子中,最优的方案是将前三头奶牛和后三头奶牛分别分为一组,中间的奶牛单独成为一组(注意一组的奶牛数量可以小于K)。这样能够有效地将7头奶牛的技能水平提高至15、15、15、9、10、10、10,和为84。
主要思路
本蒟蒻考试时水了30分(又想起水哥~),觉得这是一道好题 ! ! !妙啊!
仔细理解题目,这其实时一道最长
下降子序列的变形。
设dp[i]表示当前水平之和的最大值。 动态转移方程为:dp[i] = max(dp[j] + (i−j) ∗ max(a[j]))
枚举后面的数 Max ( a[ j ] ) ,,使得在该位上变成 (j-i+1) *Max( a[ j ] )+dp[ i-1 ],一直维护最大值。
————————AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int dp[N],a[N],n,k;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
int maxn=0;
for(int j=i;j<=min(i+k-1,n);j++){
maxn=max(maxn,a[j]);
dp[j]=max(dp[j],dp[i-1]+(j-i+1)*maxn);
}
}
printf("%d",dp[n]);
return 0;
}
——————QAQ
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122220
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话