📌  相关文章
📜  给定数组中可被 K 整除的元素的最大总和

📅  最后修改于: 2021-09-17 06:50:45             🧑  作者: Mango

给定一个整数数组和一个数字 K。任务是从给定的数组中找到可被 K 整除的最大和。
例子:

朴素的方法:递归检查所有可能的组合以找到解决方案。该解决方案具有指数时间复杂度,因此效率低下。
高效方法:一种动态规划方法,通过维护一个二维数组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


Javascript


C++14
#include 
using namespace std;
int main()
{
    int k=16;
    vectorarr={ 43, 1, 17, 26, 15 } ;
    int n=arr.size();
    vector> dp(n+2, vector(k, 0));
    for (int i = 1; i <= n; i++) {
         
        for (int j = 0; j < k ; j++) {
            dp[i][j] = dp[i - 1][j];
        }
         
        dp[i][arr[i - 1] % k] = max(dp[i][arr[i - 1] % k], arr[i - 1]);
       
        for (int j = 0; j < k; j++) {
            int m = (j + arr[i - 1]) % k;
            if (dp[i - 1][j] != 0)
                dp[i][m] = max(dp[i][m],arr[i - 1] + dp[i - 1][j]);
        }
       
    }
    cout <


输出

32

使用自顶向下 dp 的迭代实现:

我们将使用总和的索引和模值作为我们的 dp 状态。 dp[i][j] 将存储数组的最大和,直到第 i 个索引的模数为 j。

C++14

#include 
using namespace std;
int main()
{
    int k=16;
    vectorarr={ 43, 1, 17, 26, 15 } ;
    int n=arr.size();
    vector> dp(n+2, vector(k, 0));
    for (int i = 1; i <= n; i++) {
         
        for (int j = 0; j < k ; j++) {
            dp[i][j] = dp[i - 1][j];
        }
         
        dp[i][arr[i - 1] % k] = max(dp[i][arr[i - 1] % k], arr[i - 1]);
       
        for (int j = 0; j < k; j++) {
            int m = (j + arr[i - 1]) % k;
            if (dp[i - 1][j] != 0)
                dp[i][m] = max(dp[i][m],arr[i - 1] + dp[i - 1][j]);
        }
       
    }
    cout <
输出
32

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程