原题见这里
给定两个数组,A和B,都包含n个元素,对于给定的k,你需要对两个数组任意排序,但是不能交换A和B数组中的元素,使得对于排序之后的数组A'和B'有:
- 对于任意0 <= i < n,都有 A'[i] + B'[i] =>= k
给定A,B和k,问是否能满足上述条件。
这个确实是个典型的贪婪算法。
对于数组A中的元素,考虑一下,最小的那个元素,应该跟B中的哪个元素配对比较好呢?当然是,B中最大的那个元素。
A中倒数第二小的元素呢?匹配B中第二大的元素就好。
依此类推,A第三小元素匹配B第三大元素,A第i小元素匹配B第i大元素。
等等,还没证明这种方法的正确性呢。
先看A最小的元素吧。如果它跟B中最大的元素之和都没有达到k,那肯定就无解了,这个,应该,很显然吧,已经找不到能提升和的机会了。
如果只有跟B中最大的元素匹配,才能达到k,那,也很显然,只能选这个了。
除了以上两种情况之外,假设跟A最小的元素a匹配的元素是B中的b,且b不是B中最大的元素,b'才是,那么假设b'配对的是a'。有:
- a < a'
- a + b >= k
- b < b'
- a' + b' >= k
那么,可以看出 a + b' > a + b >=k,同时 a' + b > a + b >= k,也就是,交换一下它们的匹配,让a跟最大的匹配,依然成立。
因此让a和B中最大元素匹配总是对的。
然后,把a和此元素移除,剩下的的元素又可以用同样的方法,让目前A数组中最小的和目前B数组中最大的尝试匹配。
最后算法就是,对A从小到大排序,B从大到小排序,然后依次检查对应元素之和是否大于等于k即可。
具体代码见solve.php