Find sum of subset with multiplication

佐手、 提交于 2019-12-03 20:07:29

It is easier to calculate sum of multiplied triplets when repetitions are allowed (like a_1*a_1*a_1). This sum is just (sum^3).

Since repetitions are not allowed, we could just subtract them: (sum^3 - 3*sumsquares*sum).

But the above formula subtracts elements on main diagonal 3 times while it should be subtracted only once. Need to compensate this: (sum^3 - 3*sumsquares*sum + 2*sumcubes).

The above formula does not take into account 3! permutations of each triplet. So it should be divided by 3!.

Finally we have a linear-time algorithm:

  1. Compute sum of given multiset elements, sum of squares, sum of cubes.
  2. result = (sum^3 - 3*sumsquares*sum + 2*sumcubes)/6

Here is an O(n^2) approach:

sum = SUM(list)
answer = 0
for each i from 0 to n:
   sum -= list[i]
   remains = sum
   for each j from i+1 to n:
      remains -= list[j]
      answer += list[i] * list[j] * (remains)

It works because for each two elements x,y you need to sum x*y*z (for all elements z), but the sum of all possible z values is SUM(list) - x - y.

So, instead of doing: x*y*z1 + x*y*z2 + ... + x*y*z(n-2) , you basically do x*y*(z1 + ... + z(n-2))

EDIT: Editted multi-counting due to not multiplying only in the 'tail', as mentioned by @AbhishekBansal . You need to multiply each element only with the 'tail' of the list, where the tail is all the elements after the last element among x,y.

Full Working Code in C++ (Following up on Amit's idea)

#include <iostream>

using namespace std;

int main()
{
    int s[] = {3, 2, 1, 2};

    double sumOfFullList = 0;
    for ( int i = 0; i < 4; i++ )
        sumOfFullList += s[i];

    double sum = 0;

    for ( int i = 0; i < 4; i++ ) {
      double sumOfList = sumOfFullList - s[i];
      sumOfFullList -= s[i];
      for ( int j = i+1; j < 4; j++ ) {
          sumOfList -= s[j];
          sum += s[i]*s[j]*(sumOfList);
          //cout << s[i] << " " << s[j] << " " << sumOfList;
      }
    }

    cout << sum << endl;
    return 0;
}

Output:

28
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!