Find maximum subset-sum divisible by D by taking at most K elements from given array
Given an array A[] of size N, and two numbers K and D, the task is to calculate the maximum subset-sum divisible by D possible by taking at most K elements from A.
Examples:
Input: A={11, 5, 5, 1, 18}, N=5, K=3, D=7
Output:
28
Explanation:
The subset {5, 5, 18} gives the maximum sum=(5+5+18)=28 that is divisible by 7 and also has contains atmost 3 elements
Input: A={7, 7, 7, 7, 7}, N=5, K=2, D=7
Output:
14
Naive Approach: The Naive approach would be to generate all subsets of A(using bit masking), and for each subset, calculate the sum, and check whether the length of the subset is not greater than K, and the sum is divisible by D, and calculating the maximum among them.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSum(vector< int > A, int N, int K, int D)
{
int ans = 0;
for ( int i = 0; i < (1 << N); i++) {
int sum = 0;
int c = 0;
for ( int j = 0; j < N; j++) {
if (i >> j & 1) {
sum += A[j];
c++;
}
}
if (sum % D == 0 && c <= K)
ans = max(ans, sum);
}
return ans;
}
int main()
{
int N = 5, K = 3, D = 7;
vector< int > A = { 1, 11, 5, 5, 18 };
cout << maximumSum(A, N, K, D) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int maximumSum( int [] A, int N,
int K, int D)
{
int ans = 0 ;
for ( int i = 0 ; i < ( 1 << N); i++)
{
int sum = 0 ;
int c = 0 ;
for ( int j = 0 ; j < N; j++)
{
if ((i >> j & 1 ) != 0 )
{
sum += A[j];
c++;
}
}
if (sum % D == 0 && c <= K)
ans = Math.max(ans, sum);
}
return ans;
}
public static void main(String[] args)
{
int N = 5 , K = 3 , D = 7 ;
int [] A = { 1 , 11 , 5 , 5 , 18 };
System.out.print(maximumSum(A, N, K, D));
}
}
|
Python3
def maximumSum(A, N, K, D):
ans = 0
for i in range (( 1 << N)):
sum = 0
c = 0
for j in range (N):
if (i >> j & 1 ):
sum + = A[j]
c + = 1
if ( sum % D = = 0 and c < = K):
ans = max (ans, sum )
return ans
if __name__ = = '__main__' :
N = 5
K = 3
D = 7
A = [ 1 , 11 , 5 , 5 , 18 ]
print (maximumSum(A, N, K, D))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int maximumSum(List< int > A, int N,
int K, int D)
{
int ans = 0;
for ( int i = 0; i < (1 << N); i++)
{
int sum = 0;
int c = 0;
for ( int j = 0; j < N; j++)
{
if ((i >> j & 1) != 0)
{
sum += A[j];
c++;
}
}
if (sum % D == 0 && c <= K)
ans = Math.Max(ans, sum);
}
return ans;
}
public static void Main()
{
int N = 5, K = 3, D = 7;
List< int > A = new List< int >(){ 1, 11, 5, 5, 18 };
Console.Write(maximumSum(A, N, K, D));
}
}
|
Javascript
<script>
function maximumSum(A, N, K, D) {
let ans = 0;
for (let i = 0; i < (1 << N); i++) {
let sum = 0;
let c = 0;
for (let j = 0; j < N; j++) {
if (i >> j & 1) {
sum += A[j];
c++;
}
}
if (sum % D == 0 && c <= K)
ans = Math.max(ans, sum);
}
return ans;
}
let N = 5, K = 3, D = 7;
let A = [1, 11, 5, 5, 18];
document.write(maximumSum(A, N, K, D) + "<br>" );
</script>
|
Time Complexity: O(N.2N)
Auxiliary Space: O(1)
Efficient Approach: This problem can be solved with the help of dynamic programming, with a 3D dp array, where dp[i][j][p] stores the maximum sum possible if j elements are taken till the ith index and its modulo D is p. Follow the steps to solve the problem:
- Create a 3D array dp[][][] of size (N+1)x(K+1)x(D), and initialize it with -1.
- Iterate from 1 to N, and for each current index i, do the following:
- Initialize two variables element and mod to A[i-1] and A[i-1]%D.
- Copy dp[i-1] to dp[i].
- Iterate from 1 to K, and for each current index j, do the following:
- Update dp[i][j][mod] as the maximum of dp[i][j][mod] and element.
- Iterate from 0 to D-1, and for each current index p, do the following:
- If dp[i-1][j-1][p] is not equal to -1, Update dp[i][j][(p+mod)%D] as the maximum of dp[i][j][(p+mod)%D] and dp[i-1][j-1][p]+element.
- If dp[N][K][0] is -1, the answer is 0.
- Otherwise, the answer is dp[N][K][0].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSum(vector< int > A, int N, int K, int D)
{
vector<vector<vector< int > > > dp(
N + 1, vector<vector< int > >(
K + 1, vector< int >(D + 1, -1)));
for ( int i = 1; i <= N; i++) {
int element = A[i - 1];
int mod = A[i - 1] % D;
dp[i] = dp[i - 1];
for ( int j = 1; j <= K; j++) {
dp[i][j][mod] = max(dp[i][j][mod], element);
for ( int p = 0; p < D; p++) {
if (dp[i - 1][j - 1][p] != -1) {
dp[i][j][(p + mod) % D] = max(
dp[i][j][(p + mod) % D],
dp[i - 1][j - 1][p] + element);
}
}
}
}
if (dp[N][K][0] == -1)
return 0;
return dp[N][K][0];
}
int main()
{
int N = 5, K = 3, D = 7;
vector< int > A = { 1, 11, 5, 5, 18 };
cout << maximumSum(A, N, K, D) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static int maximumSum( int [] A, int N, int K, int D)
{
int [][][] dp = new int [N+ 1 ][K+ 1 ][D+ 1 ];
for ( int i = 0 ; i < N + 1 ; i++)
{
for ( int j = 0 ; j < K + 1 ; j++)
{
for ( int k = 0 ; k < D + 1 ; k++)
{
dp[i][j][k] = - 1 ;
}
}
}
for ( int i = 1 ; i <= N; i++)
{
int element = A[i - 1 ];
int mod = A[i - 1 ] % D;
dp[i] = dp[i - 1 ];
for ( int j = 1 ; j <= K; j++)
{
dp[i][j][mod] = Math.max(dp[i][j][mod], element);
for ( int p = 0 ; p < D; p++) {
if (dp[i - 1 ][j - 1 ][p] != - 1 ) {
dp[i][j][(p + mod) % D] = Math.max(
dp[i][j][(p + mod) % D],
dp[i - 1 ][j - 1 ][p] + element);
}
}
}
}
if (dp[N][K][ 0 ] == - 1 )
return 0 ;
return dp[N][K][ 0 ];
}
public static void main(String[] args)
{
int N = 5 , K = 3 , D = 7 ;
int [] A = { 1 , 11 , 5 , 5 , 18 };
System.out.print(maximumSum(A, N, K, D));
}
}
|
Python3
def maximumSum(A, N, K, D):
dp = list ()
for i in range (N + 1 ):
dp.append([ list () for _ in range (K + 1 )])
for j in range (K + 1 ):
dp[i][j] = ([ - 1 for _ in range (D + 1 )])
for i in range ( 1 , N + 1 ):
element = A[i - 1 ];
mod = A[i - 1 ] % D;
dp[i] = dp[i - 1 ];
for j in range ( 1 , K + 1 ):
dp[i][j][mod] = max (dp[i][j][mod], element);
for p in range (D):
if (dp[i - 1 ][j - 1 ][p] ! = - 1 ):
dp[i][j][(p + mod) % D] = max (
dp[i][j][(p + mod) % D],
dp[i - 1 ][j - 1 ][p] + element);
if (dp[N][K][ 0 ] = = - 1 ):
return 0 ;
return dp[N][K][ 0 ];
N, K, D = 5 , 3 , 7
A = [ 1 , 11 , 5 , 5 , 18 ];
print (maximumSum(A, N, K, D));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int maximumSum( int [] A, int N, int K, int D)
{
int [][][] dp = new int [N+1][][];
for ( int i = 0 ; i < N + 1 ; i++)
{
dp[i] = new int [K+1][];
for ( int j = 0 ; j < K + 1 ; j++)
{
dp[i][j] = new int [D+1];
for ( int k = 0 ; k < D + 1 ; k++)
{
dp[i][j][k] = -1;
}
}
}
for ( int i = 1 ; i <= N ; i++)
{
int element = A[i - 1];
int mod = A[i - 1] % D;
dp[i] = dp[i - 1];
for ( int j = 1 ; j <= K ; j++)
{
dp[i][j][mod] = Math.Max(dp[i][j][mod], element);
for ( int p = 0 ; p < D ; p++) {
if (dp[i - 1][j - 1][p] != -1) {
dp[i][j][(p + mod) % D] = Math.Max(dp[i][j][(p + mod) % D], dp[i - 1][j - 1][p] + element);
}
}
}
}
if (dp[N][K][0] == -1){
return 0;
}
return dp[N][K][0];
}
public static void Main( string [] args){
int N = 5, K = 3, D = 7;
int [] A = new int []{ 1, 11, 5, 5, 18 };
Console.Write(maximumSum(A, N, K, D));
}
}
|
Javascript
function maximumSum(A, N, K, D)
{
let dp = [];
for ( var i = 0; i < N; i++)
{
dp.push([]);
for ( var j = 0; j < K + 1; j++)
dp[i].push( new Array(D + 1).fill(-1));
}
for ( var i = 1; i <= N; i++)
{
var element = A[i - 1];
var mod = A[i - 1] % D;
dp[i] = dp[i - 1];
for ( var j = 1; j <= K; j++)
{
dp[i][j][mod] = Math.max(dp[i][j][mod], element);
for ( var p = 0; p < D; p++) {
if (dp[i - 1][j - 1][p] != -1) {
dp[i][j][(p + mod) % D] = Math.max(
dp[i][j][(p + mod) % D],
dp[i - 1][j - 1][p] + element);
}
}
}
}
if (dp[N][K][0] == -1)
return 0;
return dp[N][K][0];
}
let N = 5, K = 3, D = 7;
let A = [ 1, 11, 5, 5, 18 ];
console.log(maximumSum(A, N, K, D));
|
Time Complexity: O(NKD)
Auxiliary Space: O(NKD)
Last Updated :
20 Jul, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...