特判掉 .
显然,所有集合都用最优。
注意到如果用了 个集合,那么把剩下的数中最大的 个单独放一个集合,多余的数,一定能选出一个集合来放进去使得不会对答案产生负贡献。
枚举第一个放入第二个集合是哪个元素 ,在它之前的一定放在同一个集合里面,这样我们再知道剩余 个元素中最大的 个是多少就可以快速计算这种放法的答案了,拿个 multiset
预处理一下即可。
容易发现这样做所有情况都考虑了进去,是不重不漏的。
时间复杂度大概是个 .
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
typedef long long ll;
template <typename T> T Max(T x, T y) { return x > y ? x : y; }
template <typename T> T Min(T x, T y) { return x < y ? x : y; }
template <typename T>
T &read(T &r) {
r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
return r = w ? -r : r;
}
const int N = 114514;
int n, k;
int a[N];
ll sum, ans, b[N];
void solve() {
read(n); read(k); sum = 0;
for(int i = 1; i <= n; ++i) read(a[i]), b[i] = 0;
std::multiset<int>st;
if(n == k) {
for(int i = 1; i <= n; ++i) sum += a[i];
printf("%lld\n", sum);
return ;
}
k -= 2;
if(k) {
for(int i = n; i >= n-k+1; --i) sum += a[i], st.insert(a[i]);
b[n-k] = sum;
for(int i = n-k; i >= 3; --i) {
if(*st.begin() < a[i]) {
sum -= *st.begin();
st.erase(st.begin());
st.insert(a[i]);
sum += a[i];
}
b[i-1] = sum;
}
}
ans = sum = 0;
sum = a[1];
for(int i = 2; i <= n-k; ++i) {
ans = Max(ans, sum + b[i] + a[i]);
sum -= Min(a[i], a[i-1]);
}
printf("%lld\n", ans);
}
signed main() {
int meishayong; read(meishayong);
int T; read(T);
while(T--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?