牛牛找工作
时间限制:2秒
空间限制:65536K
为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。
View Code
View Code
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。
输出描述:
对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。
输入例子1:
3 3 1 100 10 1000 1000000000 1001 9 10 1000000000
输出例子1:
100 1000 1001
法一(借鉴):用map存储工作能力和报酬的对应关系,不仅存储所有工作的,而且也存储每个小伙伴的工作能力和报酬(为0),这样在后面计算的时候不用两层for循环,而使用一层for循环就可以搞定,
因为不需要判断小伙伴的能力值和工作能力值的大小关系,只需要计算,到目前的能力值为止,所能获得的最大报酬数,有种dp的味道,用ma保存历史最大报酬数,然后再更新到map中即可。o(nlgn)。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class MainCorrect { 2 3 public static void main(String[] args) { 4 //划重点!!!此题坑点:输入中间有空行,所以用BuffferedReader会更麻烦,所以选择用Scanner 5 Scanner sc = new Scanner(System.in); 6 int n = sc.nextInt(); 7 int m = sc.nextInt(); 8 //保存所有工作的键值对,即<工作能力,报酬>,而且也保存每个小伙伴的能力值键值对,其报酬为0 9 Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 10 //保存所有工作的能力值以及要计算的每个小伙伴的能力值 11 int[] ai = new int[m + n]; 12 for(int i = 0; i < n; i++) { 13 int di = sc.nextInt(); 14 ai[i] = di; 15 int pi = sc.nextInt(); 16 map.put(di, pi); 17 } 18 //保存要计算的每个小伙伴的能力值 19 int[] bi = new int[m]; 20 for(int i = 0; i < m; i++) { 21 ai[i + n] = sc.nextInt(); 22 bi[i] = ai[i + n]; 23 if(!map.containsKey(ai[i + n])) { 24 map.put(ai[i + n], 0); 25 } 26 } 27 //对能力值进行排序 28 Arrays.sort(ai); 29 //保存到目前的能力值为止,所能获得的最大报酬,有种dp的味道 30 int ma = 0; 31 for(int i = 0; i < m + n; i++) { 32 //每次都更新当前能力值所对应的最大报酬,由于ma是保存的<=当前能力值所能获得的最大报酬,所以可行 33 ma = Math.max(ma, map.get(ai[i])); 34 map.put(ai[i], ma); 35 } 36 //遍历每个小伙伴的能力值,从map中获取到其最大报酬(在上面的for循环中已经更新到了) 37 for(int i = 0; i < m; i++) { 38 System.out.println(map.get(bi[i])); 39 } 40 } 41 42 }
法二:两层for循环,先排序,后逐一进行比较判断。o(n^2)。当然超时,仅通过40%。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Main { 2 3 //用一个类来记录工作能力和报酬的对应关系,其实可以用map实现的 4 static class Job implements Comparable<Job>{ 5 int di, pi; 6 public Job(int di, int pi) { 7 this.di = di; 8 this.pi = pi; 9 } 10 //按工作能力值进行排序 11 public int compareTo(Job job) { 12 return this.di - job.di; 13 } 14 } 15 16 public static void main(String[] args) throws IOException { 17 Scanner sc = new Scanner(System.in); 18 int n = sc.nextInt(); 19 int m = sc.nextInt(); 20 Job[] jobs = new Job[n]; 21 for(int i = 0; i < n; i++) { 22 int di = sc.nextInt(); 23 int pi = sc.nextInt(); 24 jobs[i] = new Job(di, pi); 25 } 26 //对工作能力进行排序 27 Arrays.sort(jobs); 28 int[] ai = new int[m]; 29 for(int i = 0; i < m; i++) { 30 ai[i] = sc.nextInt(); 31 } 32 //逐一计算每个小伙伴,在其工作能力之内所能获得的最大报酬 33 for(int i = 0; i < m; i++) { 34 int j = 0; 35 int cnt = 0; 36 while(j < n && jobs[j].di <= ai[i]) { 37 if(cnt < jobs[j].pi) { 38 cnt = jobs[j].pi; 39 } 40 j++; 41 } 42 System.out.println(cnt); 43 } 44 } 45 46 }