📌  相关文章
📜  两个数组的乘积的最小和(1)

📅  最后修改于: 2023-12-03 15:21:33.756000             🧑  作者: Mango

两个数组的乘积的最小和

问题描述

给定两个长度为 n 的数组 a 和 b,你需要求出它们的乘积的最小和,也就是:

$$ \min(\sum_{i=1}^{n}a_i \times b_i) $$

保证所有数组元素均为正整数。

解决方案

这个问题可以使用贪心算法来解决。

考虑将数组 a 和 b 排序,然后将每个元素对应相乘,从小到大两两配对。这样可以使得乘积更小。

证明:

假设有两个乘积 a 和 b,满足 a < b,a 对应的元素为 a_i 和 a_j,b 对应的元素为 b_k 和 b_l,且 i < j,k < l。那么将 a_i 和 b_l 配对,将 a_j 和 b_k 配对,乘积为 a_i * b_l + a_j * b_k。与之前的 a * b 相比,减小的量为 a_i * b_j + a_j * b_i - a_i * b_l - a_j * b_k = a_i * (b_j - b_l) + a_j * (b_i - b_k)。因为 a < b,所以 b_j < b_l,b_i > b_k,因此减小的量为非负数。所以新的配对方式的乘积更小。

实现代码如下:

def min_product(a: List[int], b: List[int]) -> int:
    n = len(a)
    a.sort()
    b.sort()
    ans = 0
    for i in range(n):
        ans += a[i] * b[n - 1 - i]
    return ans
复杂度分析

时间复杂度:$\mathcal{O}(n\log n)$。

排序的时间复杂度为 $\mathcal{O}(n\log n)$,乘积是 $\mathcal{O}(n)$,所以总时间复杂度为 $\mathcal{O}(n\log n)$。

参考文献
  • 《算法竞赛进阶指南》