CF1415E New Game Plus!

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;
} 
posted @ 2026-09-02 16:36  superl61  阅读(4)  评论(0)    收藏  举报