(简单贪心)CodeForces 994B-Knights of a Polygonal Table
#
题目大意是有n个杀手,每个杀手最多能杀k个Power值比他小的人,给出n个杀手各自的Power值和Money数,问每个杀手最多能获得多少Money
定义一个结构体,内含杀手的原始索引(排序会打乱输入顺序,先记录),Power及Money,自定义对杀手Power值进行升序排序,排序后每个杀手能可能杀的人只可能位于他前面,用优先队列对前面的杀手进行入队,在k和索引范围内弹队出金钱最多的人,杀手最大金钱数等于杀的人钱数加上自身钱数
一开始我全部用sort,会超时,所以改用了优先队列,但优先队列在弹出金钱数最多杀手时需要同时出队,但是这些杀手在后面仍有可能被杀,所以用一个Temp优先队列先存出队的杀手,过后再入队。
代码:
include
include
include
include
using namespace std;
define MAX_SIZE 100005
struct Knight{
int index;
long long Power;
long long Money;
bool operator<(Knight b)const //不加const系统报错
{
return this->Money<b.Money;
}
};
Knight Member[MAX_SIZE];
long long Res[MAX_SIZE]; //储存杀手最大金钱
bool Mycmp_1(Knight a,Knight b) //对能力值升序
{return a.Power<b.Power;
}
int main()
{int n,k;
while(cin>>n>>k)
{
priority_queue<Knight> Kill_List;
priority_queue<Knight>Temp_que; //暂存出队杀手
for(int i=0;i<n;i++)
{
scanf("%lld",&Member[i].Power);
Member[i].index=i; //记录下原始索引
}
for(int i=0;i<n;i++)
scanf("%lld",&Member[i].Money);
sort(Member,Member+n,Mycmp_1); //先对能力值升序
Kill_List.push(Member[0]);
for(int i=0;i<n;i++)
{
Res[Member[i].index]=Member[i].Money; //杀手自己有的钱数
if(i==0)
continue;
for(int j=0;j<k&&j<=i-1;j++)
{
Temp_que.push(Kill_List.top()); //保存temp
Res[Member[i].index]+=Kill_List.top().Money; //杀比自己弱的人中钱多的
Kill_List.pop(); //出队
}
while(!Temp_que.empty())
{
Kill_List.push(Temp_que.top()); 将temp重新回到Kill_List
Temp_que.pop();
}
Kill_List.push(Member[i]); //已经完成的杀手入队
}
for(int i=0;i<n;i++)
cout<<Res[i]<<" ";
cout<<endl;
}
}
还没有评论,来说两句吧...