您的位置:首页 > 其它

FZU 2219 StarCraft(贪心+优先队列)

2018-02-15 20:22 225 查看

Problem Description

ZB loves playing StarCraft and he likes Zerg most!

One day, when ZB was playing SC2, he came up with an idea:

He wants to change the queen’s ability, the queen’s new ability is to choose a worker at any time, and turn it into an egg, after K units of time, two workers will born from that egg. The ability is not consumed, which means you can use it any time without cooling down.

Now ZB wants to build N buildings, he has M workers initially, the i-th building costs t[i] units of time, and a worker will die after he builds a building. Now ZB wants to know the minimum time to build all N buildings.

Input

The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

For each test case, the first line consists of three integers N, M and K. (1 <= N, M <= 100000, 1 <= K <= 100000).

The second line contains N integers t[1] … t
(1 <= t[i] <= 100000).

Output

For each test case, output the answer of the question.

Sample Input

2
3 1 1
1 3 5
5 2 2
1 1 1 1 10


Sample Output

6
10


题目大意

将一个工人放在蛋壳中,k时间之后会分裂成两个工人。初始状态下有N个建筑物,M个工人,第i 个建筑物建造需要花费ti的时间,一个工人可以建造一个建筑物,问建造这N个建筑物最少需要多少时间。

解题思路

因为初始状态下有M个工人,所以建造N个建筑物需要再创造 N-M个工人,且现有的工人应尽量让他们去建造花费时间长的建筑,留下一个工人去分裂。而一个工人分裂之后可以建造两个建筑,则应该让他们去建造花费时间尽量少的建筑。其实类似于51nod 1117 哈夫曼思想,分裂的n-m次,每次都选择花费时间最小的两个建筑,然后将次小值+K再放回总体中,n-m次分裂后,选择最大的值。

样例

5 2 4

1 1 2 2 8



代码实现

#include <iostream>
#include<queue>
#define IO ios::sync_with_stdio(false);\
cin.tie(0);\
cout.tie(0);
using namespace std;
#define maxn 100007
int t[maxn];
priority_queue<int,vector<int>,greater<int> >qu;
int main()
{
IO;
int T;
int n,m,k,z;
cin>>T;
while(T--)
{
while(!qu.empty())
qu.pop();
cin>>n>>m>>k;
for(int i=0;i<n;i++)
{
cin>>z;
qu.push(z);
}
int countt=n-m;
while(countt>0)
{
qu.pop();
int temp=qu.top();
qu.push(temp+k);
qu.pop();
countt--;
}
while(qu.size()>1)
qu.pop();
cout<<qu.top()<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: