给定n对整数,将它们分成两个子集A和B,以使得(子集A中第一个值的最大差值与子集B中第二个值的最大差值之和)最小。
示例:n = 4 {0, 0}; {5;5}; {1; 1}; {3; 4}
A = {{0; 0}; {1; 1}} B = {{5; 5}; {3; 4}} (maximum difference among first values of A, maximum difference among second values of B).
(子集A中第一个值的最大差值) = fA_max-fA_min=1-0=1 (子集B中第二个值的最大差值) = sB_max-sB_min=5-4=1 因此,答案为1+1=2,并且这是最好的方法。
显然,值之间的最大差值等于(最大值-最小值)。所以,我们需要做的是找出 (fA_max-fA_min)+(sB_max-sB_min) 的最小值。
假设给定的数组为arr[], arr[].first 表示第一个值,arr[].second 表示第二个值。
我认为在二次复杂度下解决这个问题非常容易。只需要按照第一个值进行排序。然后,子集A中的所有元素应该依次从排序数组中选取。因此,您可以遍历所有排序后的范围[L;R]。对于每个范围,尝试将该范围内的所有元素添加到子集A中,并将所有剩余元素添加到子集B中。 更详细的信息,请看这是我的C++代码:
示例:n = 4 {0, 0}; {5;5}; {1; 1}; {3; 4}
A = {{0; 0}; {1; 1}} B = {{5; 5}; {3; 4}} (maximum difference among first values of A, maximum difference among second values of B).
(子集A中第一个值的最大差值) = fA_max-fA_min=1-0=1 (子集B中第二个值的最大差值) = sB_max-sB_min=5-4=1 因此,答案为1+1=2,并且这是最好的方法。
显然,值之间的最大差值等于(最大值-最小值)。所以,我们需要做的是找出 (fA_max-fA_min)+(sB_max-sB_min) 的最小值。
假设给定的数组为arr[], arr[].first 表示第一个值,arr[].second 表示第二个值。
我认为在二次复杂度下解决这个问题非常容易。只需要按照第一个值进行排序。然后,子集A中的所有元素应该依次从排序数组中选取。因此,您可以遍历所有排序后的范围[L;R]。对于每个范围,尝试将该范围内的所有元素添加到子集A中,并将所有剩余元素添加到子集B中。 更详细的信息,请看这是我的C++代码:
int calc(pair<int, int> a[], int n){
int m = 1e9, M = -1e9, res = 2e9; //m and M are min and max of all the first values in subset A
for (int l = 1; l <= n; l++){
int g = m, G = M; //g and G are min and max of all the second values in subset B
for(int r = n; r >= l; r--) {
if (r - l + 1 < n){
res = min(res, a[r].first - a[l].first + G - g);
}
g = min(g, a[r].second);
G = max(G, a[r].second);
}
m = min(m, a[l].second);
M = max(M, a[l].second);
}
return res;
}
现在,我想将我的算法优化为loglinear复杂度。当然,首先将数组按第一个值排序。之后,如果我固定fA_min = a[i].first,那么如果索引i增加,fA_max将增加,而(sB_max - sB_min)会减少。
但现在我还是卡在这里了,有没有什么方法可以在loglinear复杂度下解决这个问题呢?
n >= 4
,集合A的子集大小应该为2或更大,集合B的子集大小也应该为2或更大,因为子集大小小于2没有意义。对吗?a[r].first - a[l].first
的溢出是否会造成问题?int
数学计算却在返回时将res
提升为long long
?