查找所有可能子集的MAX和MIN差异的总和

时间:2015-05-09 11:32:48

标签: algorithm math

给定一组元素,如何在此列表的所有子集中找到MAX和MIN之间的差异。

例如:

set = 1 2 3

Subset = {1}, max(s)-min(s) = 0.  
Subset = {2}, max(s)-min(s) = 0.
Subset = {3}, max(s)-min(s) = 0.
Subset = {1,2}, max(s)-min(s) = 1.
Subset = {2,3}, max(s)-min(s) = 1.
Subset = {1,3}, max(s)-min(s) = 2.
Subset = {1,2,3}, max(s)-min(s) = 2.

So the output will be 1+1+2+2 = 6

2 个答案:

答案 0 :(得分:17)

对列表进行排序。

排序后,第i个元素在所有(且仅有)不包含i-1个第一个元素的子集中最小,并且包含该元素。其中2^(n-i)(基于i为1时)。

同样,i将是i之后不包含任何数字的每个子集中的最高元素,并且包含i,并且2^(i-1)个这样的子集(再次,1基础)。

因此,排序后,只需迭代,并为每个i添加:

arr[i] * (2^(i-1) - 2^(n-i))

有效地按arr[i] * #times_i_is_max添加总和,并将其减少arr[i] * #times_i_is_min

在你的例子中:

sorted=1,2,3
1* (2^0 - 2^2) + 2*(2^1 - 2^1) + 3*(2^2 - 2^0) =
1*(-3) + 2*0 + 3*(3) = -3 + 0 + 9 = 6

此算法的瓶颈是排序,即O(nlogn) - 之后,所有内容都在数组的线性扫描中完成。

答案 1 :(得分:0)

@mukul 你可以计算2的所有幂并将它们存储在同时采用mod的数组中 喜欢

a[0]=1; for(i=1;i<any_no;i++)a[i]=(a[i-1]*2)%MOD;