题目大意:
输入n,k,n表示n个骑士,k表示每个骑士杀的骑士不超过k,且只能杀死力量比自己小的(题目要求每个骑士的力量都不一样),每个骑士都有自己的硬币Ci
分析:
做这题时一开始有点思路,但是bug调了好久,主要还是思路不够清晰。
我们先将骑士的力量按从小到大排序,那么在骑士前面的骑士都可以被其杀死,然后只要杀掉前面的骑士中拥有前k大的硬币的骑士,若小于k个骑士,那么全部都干掉。
如何获得前k大的硬币呢,可以利用一个从小到大排列的优先队列,里面存的就是比当前骑士力量小,前k大的硬币。因此它的大小不会超过k,若要超过k,说明要入队的比这k个中最小的大,故就把k个中最小的一个弹出,然后入队
具体看代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ll long long
ll p[N];
ll c[N];
ll num[N];
ll kill[N];
bool cmp(ll a, ll b)
{
return p[a]<p[b];
}
priority_queue<ll, vector<ll> , greater<ll> > euq;
int main()
{
ll n, k;
while(~scanf("%lld%lld",&n,&k))
{
for(int i=1;i<=n;i++)
{
scanf("%lld",&p[i]);
num[i]=i;
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&c[i]);
}
sort(num+1,num+n+1,cmp);
while(!euq.empty())
euq.pop();
ll ans=0;
for(int i=1;i<=n;i++)// 遍历num
{
kill[num[i]]=c[num[i]]+ans;
if(k>0)
{
if(euq.size()==k)
{
if(c[num[i]]>euq.top())
{
ans+=c[num[i]]-euq.top();
euq.pop();
euq.push(c[num[i]]);
}
}
else
{
ans+=c[num[i]];
euq.push(c[num[i]]);
}
}
}
for(int i=1;i<=n;i++)
{
printf("%lld ",kill[i]);
}
printf("\n");
}
return 0;
}