题目:E
题意:一次打败一个怪物,ans+=池子里的经验,池子里增加被击败怪物的经验值,ans最大多少。有最多k次机会清空池子。
当经验值为正数的时候直接放就可以了,当为负数的时候需要分析,有k次清空的机会,本质就是分成了k+1组池子,每组完了清0,要让ans最大,从大到小排序完,将负数放入k+1组池子,当负数越在某组的池子底下被减的次数也就越多,ans也就越小,谁的池子经验值高就放哪,用优先队列维护。
#include<cmath>
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
//#include<unordered_map>
#include<map>
#include<algorithm>
#include<queue>
#define mmp make_pair
#define inf 0x3f3f3f3f
#define llinf 0x7fffffffffffffff
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PP;
typedef double ld;
vector<int>h1,h2;
priority_queue<ll>que;
bool cmp(int t1,int t2) {
return t1>t2;
}
int main() {
int n,k;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;++i) {
int x; scanf("%d",&x);
if(x>=0) {
h1.push_back(x);
}
else {
h2.push_back(x);
}
}
sort(h1.begin(),h1.end(),cmp);
sort(h2.begin(),h2.end(),cmp);
ll temp=0;
ll ans=0;
for(int i=0;i<h1.size();++i) {
ans+=temp;
temp+=h1[i];
}
for(int i=1;i<=k;++i) que.push(0);
que.push(temp);
for(int i=0;i<h2.size();++i) {
ll tt=que.top();
que.pop();
ans+=tt;
que.push(tt+h2[i]);
}
printf("%lld",ans);
return 0;
}