题目:
Problem D: MJJ玩磁铁
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 139 Solved: 9
[Submit][Status][Web Board][Creator:eetze]
Description
MJJ在河北的ACM圈子中可谓是小有名气,毕竟当初一个人挑起队秒天秒地秒一切。在训练赛上多次AK江湖传闻一天不A10题晚上就睡不着觉。正是这么刻苦这么努力的MJJ,收货了一大批女粉丝,但是MJJ除了ACM以外却只喜欢玩磁铁。MJJ的班级有(N+1)个同学,(包括他自己)每个人都有手中都有一个磁铁,重量为W。每次MJJ都可以做以下行为之一:
1.每次MJJ可以挑战他的一个同学。MJJ选择一个属于他的磁铁,并把这个磁铁和他的同学的磁铁放在桌子上,用一个短距离让这两个磁铁相互吸引。假设桌子是绝对光滑的,两个磁铁会向中间移动。如果MJJ的磁铁速度比同学的磁铁速度慢,MJJ就会取得胜利,并且得到同学手中的磁铁。
2.MJJ极其擅长手工,每次他可以选择自己的两个磁铁,并将它们组合成一个新的磁铁。如果这两块磁铁的重量是U和V,那么新磁铁的重量将是(U+V),而这个操作将会消耗掉他(U+V)个单位的体力。
MJJ在今天的训练后已经非常的累了,所以他将这个问题留给了你。MJJ期望在获得最大的磁铁重量的前提下消耗最少的体力,请计算出MJJ最终的磁铁重量和其消耗的体力。
Input
第一行包含一个整数T(1≤T≤6),表示有T个测试用例。
对于每个测试用例:第一行包含一个整数N(1≤N≤100000),表示同学人数。
第二行包含N个整数W1…WN(1≤W≤100000),表示每个同学拥有的磁铁的重量。
最后一行包含一个整数M(1≤M≤100000),表示MJJ磁铁的重量。
Output
对于每个测试用例,首先输出一行“Case X:”(不带引号,X为测试用例编号,从1开始),然后输出带有两个整数的行:第一个是MJJ最终的磁铁重量,第二个是MJJ所需消耗的体力。
Sample Input
1
3
2 3 6
5
Sample Output
Case #1:
16 31
分析:如果你手中的磁铁加上你迎过来的磁铁的和能够赢过来下一块磁铁,那么就把磁铁加入到你的手中,
磁铁的合并方式永远都应该找手中最小的两个去和才能保证最小花费,因为磁铁最后要全部合在一起,所以你不用考虑合并磁铁赢取磁铁的问题,只需要判断手中所有磁铁的和是否大于下一块磁铁
当然,磁铁的重量要升序排列。
代码:
1 import java.util.Arrays; 2 import java.util.PriorityQueue; 3 import java.util.Scanner; 4 5 public class Main { 6 public static Scanner sc=new Scanner(System.in); 7 public static void main(String args[]) { 8 int time=sc.nextInt(); 9 for(int n=0;n<time;++n) 10 res(n+1); 11 } 12 public static void res(int times) { 13 PriorityQueue<Long> pq=new PriorityQueue<>(); 14 int num=sc.nextInt(); 15 long[] sti=new long[num]; 16 for(int n=0;n<num;++n) { 17 sti[n]=sc.nextLong(); 18 } 19 Arrays.sort(sti); 20 long me=sc.nextLong(); 21 pq.add(me); 22 long cost=0; 23 for(int n=0;n<num;++n) 24 if(me>sti[n]) { 25 pq.add(sti[n]); 26 me+=sti[n]; 27 } 28 else 29 break; 30 while(pq.size()>1) { 31 Long r1=pq.poll(); 32 Long r2=pq.poll(); 33 cost+=r1+r2; 34 pq.add(r1+r2); 35 } 36 System.out.println("Case #"+times+":"); 37 System.out.println(me+" "+cost); 38 } 39 }