タイトルの説明
Niu Niuは満足のいく仕事を見つけるために、各仕事の難しさと報酬を集めました。仕事を選ぶ基準は、難易度が自分の能力値を超えない場合に、報酬が最も高い仕事を選ぶことです。ニウニウが彼の仕事を選んだ後、ニウニウの友人は彼が仕事を選ぶのを手伝うためにニウニウにやって来ましたが、ニウニウは彼の友人を手伝うために彼自身の基準を使いました。Niu Niuの友達が多すぎるので、彼はあなたにこの仕事を与えなければなりません。
説明を入力してください
各入力にはテストケースが含まれています。 各テストケースの最初の行には、求人の数N(N <= 100000)と友達の数M(M <= 100000)を表す2つの正の整数が含まれています。 次のN行のそれぞれには2つの正の整数が含まれ、ジョブの難易度Di(Di <= 1000000000)と報酬Pi(Pi <= 1000000000)を示します。 次の行には、M個の小さなパートナーの能力値Ai(Ai <= 1000000000)を表すM個の正の整数が含まれています。 2つのジョブが同じ報酬を持たないことを確認してください。
出力の説明
パートナーごとに、別の行に正の整数を出力して、彼が獲得できる最高の報酬を示します。ジョブは複数の人が選択できます。
入力例
3 3 1 100 10 1000 1000000000 1001 9 10 1000000000
出力例
100 1000 1001
分析
この質問は、動的計画における01バックパックの問題のように見えますが、そうではありません。最初は、動的計画の問題であると思いました。直接01バックパックを作成したところ、Javaメモリがオーバーフローしていることがわかりました。実際、この質問の本質は最初の文にあります。言葉:仕事を選ぶための基準は、難易度が自分の能力値を超えない場合に最高の報酬を持つ仕事を選ぶことです。つまり、仕事の難易度が自分の能力以下の仕事では、その中で最高の給与を選ぶので、動的なルールではなく、並べ替えや検索が行われます。
解決策:コードに詳細なコメントを付けたところ、Niuke.comで実行して直接コピーできることが一目でわかります。
import java.util.Arrays;
import java.util.Scanner;
import java.util.TreeMap;
public class 牛牛找工作 {
public static void main(String[] args) {
//输入流
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//n表示工作的数量
int m = sc.nextInt();//m表示同学的数量
// jobs数组 n行2列 n行表示n个工作,第一列表示工作的难度, 第二列表示工作的报酬
int[][] jobs = new int[n][2];
for (int i=0;i<n;i++){
jobs[i][0] = sc.nextInt();//表示工作的难度
jobs[i][1] = sc.nextInt();//表示工作的报酬
}
//jobs数组排序
Arrays.sort(jobs, ((o1, o2) -> o1[0]-o2[0]));//按照工作难度从小到大排序
//很重要 我们把每个工作的报酬设置为 难度比他小的这些工作中的最大报酬
for (int i=1;i<jobs.length; i++){
jobs[i][1] = Math.max(jobs[i - 1][1], jobs[i][1]);
}
//将job数组存储到TreeMap中,其中,key=难度,value=最大报酬
TreeMap<Integer, Integer> map = new TreeMap<>();
for (int i=0; i<jobs.length; i++){
map.put(jobs[i][0], jobs[i][1]);
}
//输入每个同学的能力ability
for (int i=0;i<m;i++){
int ability = sc.nextInt();
//返回的是小于等于ability的最大key,其实这里就是在找这个能力下的最大工作难度
Integer key = map.floorKey(ability);
if (key != null)
//找到这个难度对应的最大报酬就是我们想得到的最大报酬
System.out.println(map.get(key));
else
System.out.println(0);
}
}
}