CF1415E New Game Plus!
可以把序列分成 \(k + 1\) 段,发现重置等价于在每一段中选一个来重置,然后进入另外一段统计贡献。
问题来了,怎么分段是最优的呢?
发现 \(n \le 5e5\),考虑 \(O(nlogn)\) 做法。不好 \(dp\),考虑贪心。
先把 \(c\) 降序排序,然后把每个 \(c_i\) 加入 \(sum_i\) 最大的一个段,这可以用堆来维护。这显然是收益最大化的。
最后答案要减去最终的 \(sum_i\) 的总和(重置)。
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
using namespace std;
using ll = long long;
const int N = 6e5;
int c[N];
int n, k;
ll ans = 0;
priority_queue<ll> q;
bool cmp(const int &x, const int &y){
return x > y;
}
void Main(){
cin >> n >> k;
F(i, 1, n) cin >> c[i];
sort(c + 1, c + n + 1, cmp);
F(i, 1, k + 1) q.push(0);
F(i, 1, n){
ll val = q.top();
q.pop();
val = val + c[i];
ans += val;
q.push(val);
}
while(q.size()){
ll val = q.top();
q.pop();
ans -= val;
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T = 1;
while(T --) Main();
return fflush(0), 0;
}

浙公网安备 33010602011771号