题目链接
https://www.acwing.com/problem/content/165/
题目:
翰翰18岁生日的时候,达达给她看了一个神奇的序列 A1,A2,…,AN。
她被允许从中选择不超过 M 个连续的部分作为自己的生日礼物。
翰翰想要知道选择元素之和的最大值。
你能帮助她吗?
输入格式
第一行包含两个整数N,M。
第二行包含N个整数A1~AN。
输出格式
输出一个整数,表示答案。
数据范围
1≤N,M≤10^5
|Ai|≤10^4
输入样例:
5 2
2 -3 2 -1 2
输出样例:
5
题解;
这道题和下边这道题做法类似:
https://blog.csdn.net/weixin_42757232/article/details/89929575
b站搜索acwing,看yxc大佬的视频学的。
视频连接:https://www.bilibili.com/video/av52497737?from=search&seid=7983071909930523707
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
typedef pair<int,int> par;
priority_queue<par,vector<par>,greater<par> > q;
int a[maxn];
int l[maxn],r[maxn];
bool st[maxn];
void remove(int p){
r[l[p]]=r[p];
l[r[p]]=l[p];
st[p]=true;
}
int main(){
int n,m;
cin>>n>>m;
int k=0;
for(int i=0;i<n;i++){
int x;
cin>>x;
if(!x) continue;
if(!k||a[k]*x<0) a[++k]=x;
else a[k]+=x;
}
n=k;
int ans=0;
int cnt=0;
for(int i=1;i<=n;i++){
if(a[i]>0){
cnt++;
ans+=a[i];
}
}
for(int i=1;i<=n;i++){
l[i]=i-1;
r[i]=i+1;
q.push(par{abs(a[i]),i});
}
while(cnt>m){
while(st[q.top().second]) q.pop();
par t=q.top();
q.pop();
int v=t.first,p=t.second;
if(l[p]!=0&&r[p]!=n+1||a[p]>0){
int L=l[p],R=r[p];
cnt--;
ans-=v;
remove(L);
remove(R);
a[p]+=a[L]+a[R];
q.push(par{abs(a[p]),p});
}else{
remove(p);
}
}
cout<<ans<<endl;
return 0;
}