Count of binary arrays of size N with sum of product of adjacent pairs equal to K
Given two integers N and K, the task is to find the total number of possible binary array of size N such that the sum of the product of adjacent pairs in that array is exactly equal to K.
Input: N = 5, K = 3
Explanation: Two combinations of array A of size N, whose sum of product of adjacent pairs adds up to K=3.
A = [1, 1, 1, 1, 0]: Value = (1*1) + (1*1) + (1*1) + (1*0) = 3
A = [0, 1, 1, 1, 1]: Value = (0*1) + (1*1) + (1*1) + (1*1) = 3
Input: N = 5, K = 4
A = [1, 1, 1, 1, 1]: Value = (1*1) + (1*1) + (1*1) + (1*1) = 4
Input: N=2, K=3
Naive Approach: The simplest approach is to find all the possible combinations of the array possible, and checking each combination individually that if its sum is equal to K or not.
Efficient Approach: Above explained simple approach can be optimized by memoising the result of each recursive call in a 3d matrix dp of size (K+1, N+1, 2), i.e. dp[K+1][N+1]. Here, each node of this dp matrix, say dp[a][b] represents the number of combinations possible of size b having sum a and last element is c where c can only be 0 or 1. Now follow the below steps to solve this problem:
- First, create a function combinationsPossible with parameters (N, idx, prev, val, K), where N is the size of the array to be formed, idx is the index till which all possible combinations of the array are possible (initially 0), prev is the previous element in the newly formed array(can only be 0 or 1), val is the sum of products till idx and K is the sum of the product of consecutive elements. This function will return the number of possible combinations till index idx having sum val and previous element prev. Also, memoise the result while returning.
- Now, from the main function call the above-stated function combinationsPossible two times with all the initial values same but only changing prev to 0 in one and 1 in another to calculate the combinations possible of all the arrays starting from 0 and 1.
- In each call check for the base cases, that are:
- If val>K: return 0, because after this index there are 0 combinations having sum K as the sum already exceeded.
- If idx=N-1: this means that the whole array of size N is formed. So just return 1 i.e. number of combinations possible, if the val is K. Otherwise, return 0.
- Also, in each recursive call check if its result is already memoised or not. If it is, then just return that from the dp array.
- Now if the previous element is 1, make two recursive calls:
- To consider the combinations possible with 1 as the current element. So, increase val by 1 in this call because the product of both current and previous element (1*1=1) will add 1 to the current sum.
- To consider the combinations possible with 0 as the current element. In this case, val will remain the same.
- If the previous element is 0, then also make two recursive calls, one to consider the combinations with 1 as the current element and another to consider the combinations with 0 as the current element. In both cases, val will remain the same.
- Add all the values returned by the above four function calls and return this added value from the current function after memoising.
- Print the answer according to the above observation.
Below is the implementation of the above approach:
Time Complexity: O(N*K)