牛客练习赛50 C. tokitsukaze and Soldier (贪心、队列维护)

题目链接:https://ac.nowcoder.com/acm/contest/1080/C

题目大意:给出n个士兵,每个士兵有v,s两个属性,分别指个人战斗力和组团限制人数(该士兵所在兵团最大人数值),问如何选择士兵,使得战斗力总和最大?

题目解答:可以给士兵按照s从大到小排序,用一个小根堆来贪心维护战斗力总和,通过遍历士兵,不断地调整小根堆(优先队列)。(大局上是枚举不同的s,确保从大到小尝试,队列里始终保持最优解,因为我们会动态地把队列里不满足s限制且战斗力最小的弹出)

代码:

#include
#define LL long long
using namespace std;
const int maxn=1e5+5;

int v[maxn],s[maxn];
int n;
struct node
{
	int v,s;
}bt[maxn];
bool cmp(node a,node b)
{
	if(a.s!=b.s)
		return a.s>b.s;
	else
		return a.v>b.v;
}
int main()
{
	//ios::sync_with_stdio(false); 
    cin>>n;
    for(int i=0;i>v>>s;
    	bt[i].v=v;
    	bt[i].s=s;
	}
	sort(bt,bt+n,cmp);
	priority_queue,greater >q;
	LL sum=0;
	LL ans=0;
	for(int i=0;ibt[i].s)
		{
			sum-=q.top();
			q.pop();
		}
		ans=max(ans,sum);
	}
	cout << ans << endl;
    return 0;
}

 

你可能感兴趣的:(acm)