Open In App

C++ Program to Maximum sum of i*arr[i] among all rotations of a given array

Given an array arr[] of n integers, find the maximum that maximizes the sum of the value of i*arr[i] where i varies from 0 to n-1.

Examples:  



Input: arr[] = {8, 3, 1, 2}
Output: 29
Explanation: Lets look at all the rotations,
{8, 3, 1, 2} = 8*0 + 3*1 + 1*2 + 2*3 = 11
{3, 1, 2, 8} = 3*0 + 1*1 + 2*2 + 8*3 = 29
{1, 2, 8, 3} = 1*0 + 2*1 + 8*2 + 3*3 = 27
{2, 8, 3, 1} = 2*0 + 8*1 + 3*2 + 1*3 = 17

Input: arr[] = {3, 2, 1}
Output: 7
Explanation: Lets look at all the rotations,
{3, 2, 1} = 3*0 + 2*1 + 1*2 = 4
{2, 1, 3} = 2*0 + 1*1 + 3*2 = 7
{1, 3, 2} = 1*0 + 3*1 + 2*2 = 7

Method 1: This method discusses the Naive Solution which takes O(n2) amount of time. 
The solution involves finding the sum of all the elements of the array in each rotation and then deciding the maximum summation value. 




// A Naive C++ program to find maximum sum rotation
#include<bits/stdc++.h>
 
using namespace std;
 
// Returns maximum value of i*arr[i]
int maxSum(int arr[], int n)
{
   // Initialize result
   int res = INT_MIN;
 
   // Consider rotation beginning with i
   // for all possible values of i.
   for (int i=0; i<n; i++)
   {
 
     // Initialize sum of current rotation
     int curr_sum = 0;
 
     // Compute sum of all values. We don't
     // actually rotate the array, instead of that we compute the
     // sum by finding indexes when arr[i] is
     // first element
     for (int j=0; j<n; j++)
     {
         int index = (i+j)%n;
         curr_sum += j*arr[index];
     }
 
     // Update result if required
     res = max(res, curr_sum);
   }
 
   return res;
}
 
// Driver code
int main()
{
    int arr[] = {8, 3, 1, 2};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << maxSum(arr, n) << endl;
    return 0;
}

Output :



29

Method 2: This method discusses the efficient solution which solves the problem in O(n) time. In the naive solution, the values were calculated for every rotation. So if that can be done in constant time then the complexity will decrease.

next_val = curr_val - (cum_sum - arr[i-1]) + arr[i-1] * (n-1);

next_val = Value of ∑i*arr[i] after one rotation.
curr_val = Current value of ∑i*arr[i] 
cum_sum = Sum of all array elements, i.e., ∑arr[i].

Lets take example {1, 2, 3}. Current value is 1*0+2*1+3*2
= 8. Shifting it by one will make it {2, 3, 1} and next value
will be 8 - (6 - 1) + 1*2 = 5 which is same as 2*0 + 3*1 + 1*2




// An efficient C++ program to compute
// maximum sum of i*arr[i]
#include<bits/stdc++.h>
 
using namespace std;
 
int maxSum(int arr[], int n)
{
    // Compute sum of all array elements
    int cum_sum = 0;
    for (int i=0; i<n; i++)
        cum_sum += arr[i];
 
    // Compute sum of i*arr[i] for initial
    // configuration.
    int curr_val = 0;
    for (int i=0; i<n; i++)
        curr_val += i*arr[i];
 
    // Initialize result
    int res = curr_val;
 
    // Compute values for other iterations
    for (int i=1; i<n; i++)
    {
        // Compute next value using previous
        // value in O(1) time
        int next_val = curr_val - (cum_sum - arr[i-1])
                       + arr[i-1] * (n-1);
 
        // Update current value
        curr_val = next_val;
 
        // Update result if required
        res = max(res, next_val);
    }
 
    return res;
}
 
// Driver code
int main()
{
    int arr[] = {8, 3, 1, 2};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << maxSum(arr, n) << endl;
    return 0;
}

Output:

29

Article Tags :