题解(依旧时间刺客)
2025-09-10 00:43:06
发布于:广东
6阅读
0回复
0点赞
解题思路
由于解密只能一关关进行,而战斗只需要关卡解密已完成就可进行,因此问题简化为:
选择k关(),求加上在解密时间上的前缀和的最小值。
建立前缀和数组存储解密时间前缀和,数组用于存储每关的战斗时间(代码中为t_),变量用于存储堆中可能为最优的k关战斗时间和(代码中为sum_),变量用于储存当前最优解(代码中为ans_)。
先把前k关战斗时间加入变量和优先队列,此时最优解可表示为。遍历接下来每一关,若其战斗时间小于当前队列中最大战斗时间,则可能成为最优解选择关卡之一,将其与最大时间交换,若新时间的确较原先最优解更优,更新。
遍历完所有关卡后,即为最优解。
实际代码
#include <bits/stdc++.h>
using namespace std;
int t[514514], t_[514514];
long long s[514514];
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, q;
cin >> n >> q;
for(int i=1;i<=n;++i){
cin >> t[i];
s[i] = s[i-1]+t[i];
} for(int i=1;i<=n;++i)
cin >> t_[i];
while(q--){
int c;
cin >> c;
priority_queue<long long> pq;
long long sum_=0, ans=LLONG_MAX;
for(int i=1;i<=n;++i){
if(pq.size()<c){
pq.push(t_[i]);
sum_ += t_[i];
} else if(t_[i]<pq.top()){
sum_ -= pq.top();
pq.pop();
pq.push(t_[i]);
sum_ += t_[i];
} if(i>=c)
ans = min(s[i]+sum_, ans);
}
cout << ans << endl;
}
}
这里空空如也
有帮助,赞一个