给定一个整数数组和一个数字K。任务是从给定数组中找到可被K整除的最大和。
例子:
Input: arr[] = {3, 6, 5, 1, 8}, k = 3
Output: 18
Explanation: 18 is formed by the elements 3, 6, 1, 8.
Input: arr = { 43, 1, 17, 26, 15 } , k = 16
Output: 32
Explanation: 32 is formed by the elements 17, 15.
天真的方法:递归检查所有可能的组合以找到解决方案。该解决方案具有指数的时间复杂度,因此效率很低。
高效方法:一种动态编程方法,通过维护一个二维数组dp来存储变量sum和i的状态(其中sum是当前和,i是整数数组的第i个索引)。通过递归所有元素,计算包括索引i处的元素的总和以及排除它,然后检查是否可被k整除。如果是这样,请将它们中的最大值存储在dp [i] [sum]中并返回。
下面的代码是上述方法的实现:
CPP
#include
using namespace std;
int dp[1001][1001];
// Function to return the maximum sum
// divisible by k from elements of v
int find_max(int i, int sum, vector& v,int k)
{
if (i == v.size())
return 0;
if (dp[i][sum] != -1)
return dp[i][sum];
int ans = 0;
// check if sum of elements excluding the
// current one is divisible by k
if ((sum + find_max(i + 1, sum, v, k)) % k == 0)
ans = find_max(i + 1, sum, v, k);
// check if sum of elements including the
// current one is divisible by k
if((sum + v[i] + find_max(i + 1,(sum + v[i]) % k,
v, k)) % k == 0)
// Store the maximum
ans = max(ans, v[i] + find_max(i + 1,
(sum + v[i]) % k,v, k));
return dp[i][sum] = ans;
}
// Driver code
int main()
{
vector arr = { 43, 1, 17, 26, 15 };
int k = 16;
memset(dp, -1, sizeof(dp));
cout << find_max(0, 0, arr, k);
}
Java
class GFG{
static int [][]dp = new int[1001][1001];
// Function to return the maximum sum
// divisible by k from elements of v
static int find_max(int i, int sum, int []v, int k)
{
if (i == v.length)
return 0;
if (dp[i][sum] != -1)
return dp[i][sum];
int ans = 0;
// check if sum of elements excluding the
// current one is divisible by k
if ((sum + find_max(i + 1, sum, v, k)) % k == 0)
ans = find_max(i + 1, sum, v, k);
// check if sum of elements including the
// current one is divisible by k
if((sum + v[i] + find_max(i + 1,(sum + v[i]) % k,
v, k)) % k == 0)
// Store the maximum
ans = Math.max(ans, v[i] + find_max(i + 1,
(sum + v[i]) % k, v, k));
return dp[i][sum] = ans;
}
// Driver code
public static void main(String[] args)
{
int []arr = { 43, 1, 17, 26, 15 };
int k = 16;
for (int i = 0; i < 1001; i++)
for (int j = 0; j < 1001; j++)
dp[i][j] = -1;
System.out.print(find_max(0, 0, arr, k));
}
}
// This code is contributed by 29AjayKumar
Python 3
# Python3 implementation
dp = [[-1 for i in range(1001)] for j in range(1001)]
# Function to return the maximum sum
# divisible by k from elements of v
def find_max(i, sum, v, k):
if (i == len(v)):
return 0
if (dp[i][sum] != -1):
return dp[i][sum]
ans = 0
# check if sum of elements excluding the
# current one is divisible by k
if ((sum + find_max(i + 1, sum, v, k)) % k == 0):
ans = find_max(i + 1, sum, v, k)
# check if sum of elements including the
# current one is divisible by k
if((sum + v[i] + find_max(i + 1,(sum + v[i]) % k, v, k)) % k == 0):
# Store the maximum
ans = max(ans, v[i] + find_max(i + 1,(sum + v[i]) % k, v, k))
dp[i][sum] = ans
return dp[i][sum]
# Driver code
if __name__ == '__main__':
arr = [43, 1, 17, 26, 15]
k = 16
print(find_max(0, 0, arr, k))
# This code is contributed by Surendra_Gangwar
C#
using System;
class GFG{
static int [,]dp = new int[1001,1001];
// Function to return the maximum sum
// divisible by k from elements of v
static int find_max(int i, int sum, int []v, int k)
{
if (i == v.Length)
return 0;
if (dp[i,sum] != -1)
return dp[i,sum];
int ans = 0;
// check if sum of elements excluding the
// current one is divisible by k
if ((sum + find_max(i + 1, sum, v, k)) % k == 0)
ans = find_max(i + 1, sum, v, k);
// check if sum of elements including the
// current one is divisible by k
if((sum + v[i] + find_max(i + 1,(sum + v[i]) % k,
v, k)) % k == 0)
// Store the maximum
ans = Math.Max(ans, v[i] + find_max(i + 1,
(sum + v[i]) % k, v, k));
return dp[i, sum] = ans;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 43, 1, 17, 26, 15 };
int k = 16;
for (int i = 0; i < 1001; i++)
for (int j = 0; j < 1001; j++)
dp[i,j] = -1;
Console.Write(find_max(0, 0, arr, k));
}
}
// This code is contributed by 29AjayKumar
输出:
32