1. 程式人生 > >Minimum Cost to Hire K Workers

Minimum Cost to Hire K Workers

There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i].

Now we want to hire exactly K workers to form a paid group.  When hiring a group of K workers, we must pay them according to the following rules:

  1. Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
  2. Every worker in the paid group must be paid at least their minimum wage expectation.

Return the least amount of money needed to form a paid group satisfying the above conditions.

 

Example 1:

Input: quality = [10,20,5], wage = [70,50,30], K = 2
Output: 105.00000
Explanation: We pay 70 to 0-th worker and 35 to 2-th worker.

Example 2:

Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3
Output: 30.66667
Explanation: We pay 4 to 0-th worker, 13.33333 to 2-th and 3-th workers seperately. 

 

Note:

  1. 1 <= K <= N <= 10000, where N = quality.length = wage.length
  2. 1 <= quality[i] <= 10000
  3. 1 <= wage[i] <= 10000
  4. Answers within 10^-5 of the correct answer will be considered correct.

題目理解:

給定n個工人,每個工人有自己的工作能力,以及最低工資標準,需要招聘K個工人,每個工人得到工資必須與他們之間的工作能力成正比,而且不能低於每個人的最低工資標準,問花的錢最少是多少。

解題思路:

題目中說,工資必須要與工作能力成正比,也就是說,每個工人的工資是一個常數p與其工作能力的乘積;那麼為了花最少的錢,我們一定會選一個最小的常數p,這個p其實就是每個工人的單位工作能力的價格;因為不能低於最低工資標準,所以我們一定要選擇全部K個工人當中的最大的p,才能使得工資不低於所有人各自的最低工資標準;

在選定某一個p之後,我們選出來單位工作能力價格小於或者等於p的所有工人,在這些工人當中選出工作能力最低的K個工人,花費的價格就是就是在當前p的條件下最低的費用,我們遍歷所有的p之後,就能得到最低花費。

程式碼如下:

class Solution {
	class node implements Comparable<node>{

		int quality;
		double price;
		public node(int q, double p) {
			quality = q;
			price = p;
		}
		
		@Override
		public int compareTo(node a) {
			// TODO Auto-generated method stub
			if(Math.abs(this.price - a.price) < 0.000001)
				return 0;
			return this.price < a.price ? -1 : 1;
		}
		
	}
	
    public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
    	int len = quality.length;
    	List<node> list = new ArrayList<node>();
    	for(int i = 0; i < len; i++) {
    		list.add(new node(quality[i], 1.0 * wage[i] / quality[i]));
    	}
    	Collections.sort(list);
    	double res = Double.MAX_VALUE;
    	int sum = 0;
    	PriorityQueue<Integer> qu = new PriorityQueue<Integer>(Collections.reverseOrder());
    	for(node it : list) {
    		sum += it.quality;
    		qu.offer(it.quality);
    		if(qu.size() > K) {
    			sum -= qu.poll();
    		}
    		if(qu.size() == K) {
    			res = Math.min(res, sum * it.price);
    			//System.out.println(sum + " " + res);
    		}
    	}
    	return res;
    }
}