C++ 子集差之和


在这个问题中,我们给定一个包含 n 个数字的集合 S。我们的任务是创建一个程序来查找子集差之和,即子集的最后一个元素和第一个元素之间的差。

公式为:

sumSubsetDifference = Σ [last(s) - first(s)]
s are subsets of the set S.

让我们举个例子来理解这个问题:

输入 -

S = {1, 2, 9} n = 3

输出 -

解释 - 所有子集为 -

{1}, last(s) - first(s) = 0
{2}, last(s) - first(s) = 0
{9}, last(s) - first(s) = 0
{1, 2}, last(s) - first(s) = 1
{1, 9}, last(s) - first(s) = 8
{2, 9}, last(s) - first(s) = 7
{1, 2, 9}, last(s) - first(s) = 8
Sum = 1 + 8 + 7 + 8 = 24

解决此问题的一个简单方法是找到所有子集的最后一个元素和第一个元素之间的差,然后将它们加起来得到输出总和。这不是最有效的解决方案,因此让我们讨论一个更有效的解决方案。

对于一个包含 n 个元素的集合 S,总和也可以使用从数组元素开始的所有子集的数量来计算。然后将其相加以找到结果。

所以,

sumSetDifference(S) = Σ [last(s) - Σfirst(s)]

所以,对于一个包含元素 {s1, s2, s3, … sn} 的集合 S。

以 s1 开头的子集可以使用元素 {s2, s3, … sn} 的组合来创建。这将产生 2n-1 个集合。

类似地,以 s2 开头的子集产生 2n-2 个集合。

将其推广,以 Si 开头的子集给出 2n-i

因此,所有子集的第一个元素之和为 -

SumFirst = a1.2n-1 + a2.2n-2 + a3.2n-3 + … + an.2n-n

类似地,我们将计算固定最后一个元素的 sumLast。

SumLast = a1.2n-n + a1.2n - (n-1) + a3.2n - (n-2) + ... + an.2n - (n-(n-1))

示例

说明上述解决方案的程序:

实时演示

#include<iostream>
#include<math.h>
using namespace std;
int CalcSumFirst(int S[], int n) {
   int sum = 0;
   for (int i = 0; i < n; i++)
      sum = sum + (S[i] * pow(2, n-i-1));
   return sum;
}
int CalcSumLast(int S[], int n) {
   int sum = 0;
   for (int i = 0; i < n; i++)
      sum = sum + (S[i] * pow(2, i));
   return sum;
}
int main() {
   int S[] = {1, 4, 9, 6};
   int n = 4;
   int sumSetDiff = CalcSumLast(S, n) - CalcSumFirst(S, n);
   printf("The sum of subset differences is %d", sumSetDiff);
   return 0;
}

输出

The sum of subset differences is 45

更新于:2020-08-05

199 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告