Minimise sum of products of positions of each element with element at (i+K)%N
Last Updated :
04 Apr, 2022
Given an array Arr[] of integers of size N, The task is to find the minimum value of the given function when applied on the array.
S(K) = 1 * Arr[(0 + K)%N] + 2 * Arr[(1 + K)%N] + 3 * Arr[(2 + K)%N] + . . . . . . . + N * Arr[((N-1) + K)%N]
= ∑[(i+1)∗Arr[(i+K)%N]
where K is a whole number.
Examples:
Input: Arr[] = {2, 1, 4, 3}
Output: 20
Explanation: S(0) = 28, S(1) = 26, S(2) = 20, S(3) =26, S(4) = S(0), S(5) = S(1). . . . .
Thus there are only four possible values of the function and minimum is 20.
Input: Arr[] = {-3, 2, 1}
Output: -5
Explanation: S(0) = 4, S(1) = -5, S(2) = 1, S(3) = S(0), S(4) = S(1), S(5) = S(2) . . . . .
Thus there are only three possible values of the function and minimum is -5.
Naive Approach: The basic approach to solve the problem is to calculate the value of the function for all values of K in range [0, N-1].
Follow the steps mentioned below to solve the problem:
- It can be observed that if the Arr has length N then the given function can only have N distinct values.
- Find all the possible values of the function S(k) separately from k = 0 to N – 1 and print the minimum value among them.
Below is the implementation of the naive approach.
C++
#include <bits/stdc++.h>
using namespace std;
int fnValueAtk(vector< int > Arr, int k)
{
int sum = 0;
int N = Arr.size();
for ( int i = 0; i < N; i++) {
sum += (i + 1) * Arr[(i + k) % N];
}
return sum;
}
void minValFn(vector< int > Arr)
{
int N = Arr.size();
int min_val = INT_MAX;
for ( int k = 0; k < N; k++) {
int fn_At_k = fnValueAtk(Arr, k);
min_val = min(min_val, fn_At_k);
}
cout << min_val;
}
int main()
{
vector< int > Arr = { 2, 1, 4, 3 };
minValFn(Arr);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void minValFn( int [] Arr)
{
int N = Arr.length;
int min_val = Integer.MAX_VALUE;
for ( int k = 0 ; k < N; k++) {
int fn_At_k = fnValueAtk(Arr, k);
min_val = Math.min(min_val, fn_At_k);
}
System.out.println(min_val);
}
static int fnValueAtk( int [] Arr, int k)
{
int sum = 0 ;
int N = Arr.length;
for ( int i = 0 ; i < N; i++) {
sum += (i + 1 ) * Arr[(i + k) % N];
}
return sum;
}
public static void main(String[] args)
{
int [] Arr = { 2 , 1 , 4 , 3 };
minValFn(Arr);
}
}
|
Python3
import sys
def fnValueAtk(Arr, k):
sums = 0
N = len (Arr)
for i in range (N):
sums + = (i + 1 ) * Arr[(i + k) % N]
return sums
def minValFn(Arr):
N = len (Arr)
min_val = sys.maxsize
for k in range (N):
fn_At_k = fnValueAtk(Arr, k)
min_val = min (min_val, fn_At_k)
print (min_val)
Arr = [ 2 , 1 , 4 , 3 ]
minValFn(Arr)
|
C#
using System;
public class GFG{
static void minValFn( int [] Arr)
{
int N = Arr.Length;
int min_val = Int32.MaxValue;
for ( int k = 0; k < N; k++) {
int fn_At_k = fnValueAtk(Arr, k);
min_val = Math.Min(min_val, fn_At_k);
}
Console.WriteLine(min_val);
}
static int fnValueAtk( int [] Arr, int k)
{
int sum = 0;
int N = Arr.Length;
for ( int i = 0; i < N; i++) {
sum += (i + 1) * Arr[(i + k) % N];
}
return sum;
}
static public void Main (){
int [] Arr = { 2, 1, 4, 3 };
minValFn(Arr);
}
}
|
Javascript
function fnValueAtk(Arr, k)
{
var sum = 0;
var N = Arr.length;
for ( var i = 0; i < N; i++)
{
sum += (i + 1) * Arr[(i + k) % N];
}
return sum;
}
function minValFn(Arr)
{
var N = Arr.length;
var min_val = Number.MAX_SAFE_INTEGER;
for ( var k = 0; k < N; k++)
{
var fn_At_k = fnValueAtk(Arr, k);
min_val = Math.min(min_val, fn_At_k);
}
document.write(min_val);
}
var Arr = [2, 1, 4, 3];
minValFn(Arr);
|
Time Complexity: O(N2).
Auxiliary Space: O(1)
Efficient approach: The efficient approach to solve the problem is based on the following relations among S(k) and S(k-1):
S(k) = S(k – 1) – Sum + Arr[(k-1)%N] * N
Refer to the illustration below for a better understanding.
Illustration:
Suppose the array is {2, 1, 4, 3}
Now, to find the value of the function given in the problem:
= 1 * Arr[(0 + k)%N] + 2 * Arr[(1 + k)%N] + 3 * Arr[(2 + k)%N] + . . . . . . . + N * Arr[((N-1) + k)%N]
- Now, for k = 0;
S(0) = 1* Arr[0] + 2* Arr[1] + 3* Arr[2] + 4* Arr[3]
= 1*2 + 2*1 + 3*4 + 4*3
= 28 - similarly, for k = 1;
S(1) = 1* Arr[1] + 2* Arr[2] + 3* Arr[3] + 4* Arr[0]
= 1*1 + 2*4 + 3*3 + 4*2
= 26 - similarly, for k = 2;
S(2) = 20 - similarly, for k = 3;
s(3) = 26 - Now, S(4) = S(0), S(5) = S(1). . . . and so on.
Hence the minimum value of function is S(2) = 20;
Now, it can be solved using derived equation: S(k) = S(k – 1) – Sum + Arr[(k-1)%N] * N
Firstly, store the value of S(0) (k = 0) in some variable by traversing the array and then use the above mentioned equation to find the values of function for k = 1, 2, 3 and so on.
Later compare the value of S(k) with S(0) and update it with the minimum one. Follow the below steps:
- Now, the value of function when k = 0 S(0) is 28, and total sum is 10, then to find the value for k = 1
using equation,
for k = 1: S(1) = 28 – 10 + Arr[(1 – 1) % 4] * 4
= 28 – 10 + 8
= 26 (which is less than S(0) hence update the minimum value with S(1)) - For k = 2: S(2) = 26 – 10 + Arr[(2 – 1) % 4]* 4
= 26 – 10 + 4
= 20 (which is less than S(1) hence update the minimum value with S(2)) - For k = 3: S(3) = 20 – 10 + Arr[(3 – 1) % 4]* 4
= 20 – 10 + 16
= 26 (which is not less than S(2) hence, do not update the value with S(3))
Hence, S(2) is the minimum value of function.
Follow the steps mentioned below to implement the above observation:
- Declare a variable ‘min_val’ to store the minimum value of the given function.
- Find S(0) in a single traversal of the array and store it in ‘min_val’.
- Then find all the possible values of function S(k) for k = 1 to N – 1 using the above equation.
- If this value is smaller than ‘min_val’ then update ‘min_val’.
- The final value of min_val is the required answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void minValFn(vector< int > Arr)
{
int N = Arr.size();
int min_val;
int sum = 0;
int s0 = 0;
for ( int i = 0; i < N; i++) {
s0 += Arr[i] * (i + 1);
sum += Arr[i];
}
min_val = s0;
int sk_min_1 = s0;
for ( int k = 1; k < N; k++) {
int sk = sk_min_1 - sum + Arr[(k - 1) % N] * N;
min_val = min(sk, min_val);
sk_min_1 = sk;
}
cout << min_val << "\n" ;
}
int main()
{
vector< int > Arr = { 2, 1, 4, 3 };
minValFn(Arr);
}
|
Java
import java.io.*;
public class GFG {
static void minValFn( int [] Arr)
{
int N = Arr.length;
int min_val;
int sum = 0 ;
int s0 = 0 ;
for ( int i = 0 ; i < N; i++) {
s0 += Arr[i] * (i + 1 );
sum += Arr[i];
}
min_val = s0;
int sk_min_1 = s0;
for ( int k = 1 ; k < N; k++) {
int sk = sk_min_1 - sum
+ Arr[(k - 1 ) % N] * N;
min_val = Math.min(sk, min_val);
sk_min_1 = sk;
}
System.out.println(min_val);
}
public static void main(String[] args)
{
int [] Arr = { 2 , 1 , 4 , 3 };
minValFn(Arr);
}
}
|
Python3
def minValFn(Arr):
N = len (Arr)
sums = 0
s0 = 0
for i in range (N):
s0 + = Arr[i] * (i + 1 )
sums + = Arr[i]
min_val = s0
sk_min_1 = s0
for k in range ( 1 , N):
sk = sk_min_1 - sums + Arr[(k - 1 ) % N] * N
min_val = min (sk, min_val)
sk_min_1 = sk
print (min_val)
Arr = [ 2 , 1 , 4 , 3 ]
minValFn(Arr)
|
C#
using System;
public class GFG {
static void minValFn( int [] Arr)
{
int N = Arr.Length;
int min_val;
int sum = 0;
int s0 = 0;
for ( int i = 0; i < N; i++) {
s0 += Arr[i] * (i + 1);
sum += Arr[i];
}
min_val = s0;
int sk_min_1 = s0;
for ( int k = 1; k < N; k++) {
int sk = sk_min_1 - sum
+ Arr[(k - 1) % N] * N;
min_val = Math.Min(sk, min_val);
sk_min_1 = sk;
}
Console.Write(min_val);
}
public static void Main( string [] args)
{
int [] Arr = { 2, 1, 4, 3 };
minValFn(Arr);
}
}
|
JavaScript
<script>
const minValFn = (Arr) => {
let N = Arr.length;
let min_val;
let sum = 0;
let s0 = 0;
for (let i = 0; i < N; i++) {
s0 += Arr[i] * (i + 1);
sum += Arr[i];
}
min_val = s0;
let sk_min_1 = s0;
for (let k = 1; k < N; k++) {
let sk = sk_min_1 - sum + Arr[(k - 1) % N] * N;
min_val = Math.min(sk, min_val);
sk_min_1 = sk;
}
document.write(min_val);
}
let Arr = [2, 1, 4, 3];
minValFn(Arr);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...