一个工人可以变成两个工人,这样可以画出一颗二叉树,那么就是在叶子上建的建筑。
问题的时间花费,可以看作是这颗二叉树中各个叶子的深度*k+叶子对应建筑耗费时间中的最大值。
容易想到,类似哈夫曼树一样,从叶子出发往上合并,直到连通分量数小于等于m,结点的权值设定为w=max(lw,rw)+k。
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 using namespace std; 5 int main(){ 6 int t,n,m,k,a; 7 scanf("%d",&t); 8 while(t--){ 9 scanf("%d%d%d",&n,&m,&k); 10 priority_queue<int, vector<int>, greater<int> > que; 11 for(int i=0;i<n;++i){ 12 scanf("%d",&a); 13 que.push(a); 14 } 15 while(n>m){ 16 int w1=que.top(); que.pop(); 17 int w2=que.top(); que.pop(); 18 que.push(w2+k); 19 --n; 20 } 21 int res=0; 22 while(!que.empty()){ 23 res=max(res,que.top()); 24 que.pop(); 25 } 26 printf("%d\n",res); 27 } 28 return 0; 29 }