Given an array **arr[]** and an integer **K**, the task is to find out the minimum product of a subsequence where adjacent elements of the subsequence are separated by a maximum distance of K.

**Note:** The subsequence should include the first and the last element of the array.

**Examples:**

Input:arr[] = { 1, 2, 3, 4 }, K = 2

Output:8

The first element in the subsequence is 1. From 1, we can move to either 2 or 3 (since K = 2). We can move to 3 and then to 4 to have a product of 12. However,we can also move to 2 and then to 4to have a product of 8. Minimal product subsequence = { 1, 2, 4 }

Input:arr[] = { 2, 3 }, K = 2

Output:6

**Naive Approach:** A naive approach is to generate all subsequences of the array and maintain a difference of indices between the adjacent elements and find the minimal product subsequence.

**Efficient Approach:** An efficient approach is to use **dynamic programming**. Let **dp[i]** denote the minimum product of elements **till index ‘i’ including arr[i]** who are separated by a maximum distance of **K**. Then dp[i] can be formulated as follows:

dp[i] = arr[i] * min{dp[j]} where j < i and 1 <= i - j <= K.

To calculate **dp[i]**, a window of size **K** can be maintained and traversed to find the minimum of **dp[j]** which can then be **multiplied to arr[i]**. However, this will result in an **O(N*K)** solution.

To optimize the solution further, values of the product can be stored in an STL set and the minimum value of the product can then be found out in **O(log n)** time. Since storing products can be a cumbersome task since the product can easily exceed 10^{18}, therefore we will store log values of products since log is a monotonic function and minimization of log values will automatically imply minimization of products.

Below is the implementation of the above approach:

`// C++ implementation of the above approach. ` `#include <bits/stdc++.h> ` ` ` `#define mp make_pair ` `#define ll long long ` `using` `namespace` `std; ` ` ` `const` `int` `mod = 1000000007; ` `const` `int` `MAX = 100005; ` ` ` `// Function to get the minimum product of subsequence such that ` `// adjacent elements are separated by a max distance of K ` `int` `minimumProductSubsequence(` `int` `* arr, ` `int` `n, ` `int` `k) ` `{ ` ` ` `multiset<pair<` `double` `, ` `int` `> > s; ` ` ` ` ` `ll dp[MAX]; ` ` ` `double` `p[MAX]; ` ` ` ` ` `dp[0] = arr[0]; ` ` ` `p[0] = ` `log` `(arr[0]); ` ` ` ` ` `// multiset will hold pairs ` ` ` `// pair = (log value of product, dp[j] value) ` ` ` `// dp[j] = minimum product % mod ` ` ` `// multiset will be sorted according to log values ` ` ` `// Therefore, corresponding to the minimum log value ` ` ` `// dp[j] value can be obtained. ` ` ` `s.insert(mp(p[0], dp[0])); ` ` ` ` ` `// For the first k-sized window. ` ` ` `for` `(` `int` `i = 1; i < k; i++) { ` ` ` ` ` `double` `l = (s.begin())->first; ` ` ` `ll min = (s.begin())->second; ` ` ` ` ` `// Update log value by adding previous ` ` ` `// minimum log value ` ` ` `p[i] = ` `log` `(arr[i]) + l; ` ` ` `// Update dp[i] ` ` ` `dp[i] = (arr[i] * min) % mod; ` ` ` ` ` `// Insert it again into the multiset ` ` ` `// since it is within the k-size window ` ` ` `s.insert(mp(p[i], dp[i])); ` ` ` `} ` ` ` ` ` `for` `(` `int` `i = k; i < n; i++) { ` ` ` ` ` `double` `l = (s.begin())->first; ` ` ` `ll min = (s.begin())->second; ` ` ` ` ` `p[i] = ` `log` `(arr[i]) + l; ` ` ` `dp[i] = (arr[i] * min) % mod; ` ` ` ` ` `// Eliminate previous value which falls out ` ` ` `// of the k-sized window ` ` ` `multiset<pair<` `double` `, ` `int` `> >::iterator it; ` ` ` `it = s.find(mp(p[i - k], dp[i - k])); ` ` ` `s.erase(it); ` ` ` ` ` `// Insert newest value to enter in ` ` ` `// the k-sized window. ` ` ` `s.insert(mp(p[i], dp[i])); ` ` ` `} ` ` ` ` ` `// dp[n - 1] will have minimum product % ` ` ` `// mod such that adjacent elements are ` ` ` `// separated by a max distance K ` ` ` `return` `dp[n - 1]; ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `int` `arr[] = { 1, 2, 3, 4 }; ` ` ` `int` `n = ` `sizeof` `(arr) / ` `sizeof` `(arr[0]); ` ` ` `int` `k = 2; ` ` ` ` ` `cout << minimumProductSubsequence(arr, n, k); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

8

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Maximum length subsequence such that adjacent elements in the subsequence have a common factor
- Minimal moves to form a string by adding characters or appending string itself
- Find side of Square which makes minimal area to fit two identical rectangles inside it
- Maximum subsequence sum such that all elements are K distance apart
- Maximum length subsequence with difference between adjacent elements as either 0 or 1
- Maximum subsequence sum with adjacent elements having atleast K difference in index
- Maximum subsequence sum of at most K-distant adjacent elements
- Cost of creating smallest subsequence with sum of difference between adjacent elements maximum
- Print Triangle separated pattern
- Python | Number of elements to be removed such that product of adjacent elements is always even
- Longest subsequence such that adjacent elements have at least one common digit
- Length of the longest increasing subsequence such that no two adjacent elements are coprime
- Length of the longest subsequence such that xor of adjacent elements is non-decreasing
- Maximum product from array such that frequency sum of all repeating elements in product is less than or equal to 2 * k
- Count maximum occurrence of subsequence in string such that indices in subsequence is in A.P.
- Distance of chord from center when distance between center and another equal length chord is given
- Arrange N elements in circular fashion such that all elements are strictly less than sum of adjacent elements
- Find the Increasing subsequence of length three with maximum product
- Maximum product of a triplet (subsequence of size 3) in array
- Maximum product of an increasing subsequence of size 3

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.