NC207751 牛牛的旅游纪念品

题目链接

题目

题目描述

牛牛在牛市的旅游纪念商店里面挑花了眼,于是简单粗暴的牛牛决定——买最受欢迎的就好了。

但是牛牛的背包有限,他只能在商店的n个物品里面带m个回去,不然就装不下了。

并且牛牛希望买到的纪念品不要太相似,所以导购小姐姐帮助牛牛把纪念品全部排成了一行,牛牛只需要让选出来要买的m个物品中任意两个的位置差都大于等于k就行了。

现在告诉你这n个物品排成一行之后的受欢迎程度(可能是负数),求牛牛带回去的m个物品的最大欢迎度之和。

输入描述

第一行三个数n,m,k 接下来一行,有n个整数,是n个物品按顺序的受欢迎程度。

输出描述

输出一个数为题目所求的最大和

示例1

输入

4 2 2
2 4 -6 1

输出

5

说明

n10000,m100,mn ,答案保证在int范围内,保证按照题目要求一定能取到m个物品

题解

知识点:背包dp。

一个01背包变形,第 i 个物品要从 ik 转移。因此如 dp[i][0] 的初始化要手写而不能递推下去了。有转移方程:

dp[i][j]=max(dp[max(0,ik)][j1]+a[i],dp[i1][j])

因为 i<k 时,也是能选自己的因此用一个 max 限制一下。

时间复杂度 O(nm)

空间复杂度 O(nm)

代码

#include <bits/stdc++.h>
using namespace std;
int a[10007], dp[10007][107];
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m, k;
cin >> n >> m >> k;
for (int i = 1;i <= n;i++) cin >> a[i];
memset(dp, -0x3f, sizeof(dp));
dp[0][0] = 0;
for (int i = 1;i <= n;i++) {
dp[i][0] = 0;
for (int j = 1;j <= m;j++) {
dp[i][j] = max(dp[max(0, i - k)][j - 1] + a[i], dp[i - 1][j]);
///i<k时,还有j=1时候能选自己即,dp[0][0] + a[i]所以不能if掉
}
}
cout << dp[n][m] << '\n';
return 0;
}
posted @   空白菌  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示