📌  相关文章
📜  不超过 K 的非相邻数组元素的最大可能总和

📅  最后修改于: 2021-10-27 07:31:18             🧑  作者: Mango

给定一个由N 个整数和一个整数K组成的数组arr[] ,任务是选择一些最大可能总和不超过K 的非相邻数组元素

例子:

朴素的方法:最简单的方法是递归生成给定数组的所有可能子集,对于每个子集,检查它是否不包含相邻元素并且总和不超过K 。在发现上述条件为真的所有子集中,打印为任何子集获得的最大和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the
// maximum sum not exceeding
// K possible by selecting
// a subset of non-adjacent elements
int maxSum(int a[],
           int n, int k)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Not selecting current
  // element
  int option = maxSum(a,
                      n - 1, k);
 
  // If selecting current
  // element is possible
  if (k >= a[n - 1])
    option = max(option,
                 a[n - 1] +
             maxSum(a, n - 2,
                    k - a[n - 1]));
 
  // Return answer
  return option;
}
 
// Driver Code
int main()
{
  // Given array arr[]
  int arr[] = {50, 10,
               20, 30, 40};
 
  int N = sizeof(arr) /
          sizeof(arr[0]);
 
  // Given K
  int K = 100;
 
  // Function Call
  cout << (maxSum(arr,
                  N, K));
}
 
// This code is contributed by gauravrajput1


Java
// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to find the maximum sum
    // not exceeding K possible by selecting
    // a subset of non-adjacent elements
    public static int maxSum(
        int a[], int n, int k)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Not selecting current element
        int option = maxSum(a, n - 1, k);
 
        // If selecting current element
        // is possible
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1]));
 
        // Return answer
        return option;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given array arr[]
        int arr[] = { 50, 10, 20, 30, 40 };
 
        int N = arr.length;
 
        // Given K
        int K = 100;
 
        // Function Call
        System.out.println(maxSum(arr, N, K));
    }
}


Python3
# Python3 program for the above approach
 
# Function to find the maximum sum
# not exceeding K possible by selecting
# a subset of non-adjacent elements
def maxSum(a, n, k):
     
    # Base Case
    if (n <= 0):
        return 0
 
    # Not selecting current element
    option = maxSum(a, n - 1, k)
 
    # If selecting current element
    # is possible
    if (k >= a[n - 1]):
        option = max(option, a[n - 1] +
        maxSum(a, n - 2, k - a[n - 1]))
 
    # Return answer
    return option
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 50, 10, 20, 30, 40 ]
 
    N = len(arr)
 
    # Given K
    K = 100
 
    # Function Call
    print(maxSum(arr, N, K))
 
# This code is contributed by mohit kumar 29


C#
// C# program for the
// above approach
using System;
class GFG{
 
// Function to find the maximum
// sum not exceeding K possible
// by selecting a subset of
// non-adjacent elements
public static int maxSum(int []a,
                         int n, int k)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Not selecting current element
  int option = maxSum(a, n - 1, k);
 
  // If selecting current
  // element is possible
  if (k >= a[n - 1])
    option = Math.Max(option, a[n - 1] +
                      maxSum(a, n - 2,
                             k - a[n - 1]));
   
  // Return answer
  return option;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array []arr
  int []arr = {50, 10, 20, 30, 40};
 
  int N = arr.Length;
 
  // Given K
  int K = 100;
 
  // Function Call
  Console.WriteLine(maxSum(arr, N, K));
}
}
 
// This code is contributed by Rajput-Ji


Javascript


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Initialize dp
int dp[1005][1005];
 
// Function find the maximum sum that
// doesn't exceeds K by choosing elements
int maxSum(int* a, int n, int k)
{
     
    // Base Case
    if (n <= 0)
        return 0;
 
    // Return the memoized state
    if (dp[n][k] != -1)
        return dp[n][k];
 
    // Dont pick the current element
    int option = maxSum(a, n - 1, k);
 
    // Pick the current element
    if (k >= a[n - 1])
        option = max(option,
                     a[n - 1] +
             maxSum(a, n - 2,
                 k - a[n - 1]));
 
    // Return and store the result
    return dp[n][k] = option;
}
 
// Driver Code
int main()
{
    int N = 5;
 
    int arr[] = { 50, 10, 20, 30, 40 };
 
    int K = 100;
 
    // Fill dp array with -1
    memset(dp, -1, sizeof(dp));
 
    // Print answer
    cout << maxSum(arr, N, K) << endl;
}
 
// This code is contributed by bolliranadheer


Java
// Java program for the above approach
 
import java.util.*;
 
class GFG {
 
    // Function find the maximum sum that
    // doesn't exceeds K by choosing elements
    public static int maxSum(int a[], int n,
                             int k, int[][] dp)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Return the memoized state
        if (dp[n][k] != -1)
            return dp[n][k];
 
        // Dont pick the current element
        int option = maxSum(a, n - 1,
                            k, dp);
 
        // Pick the current element
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
        // Return and store the result
        return dp[n][k] = option;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 50, 10, 20, 30, 40 };
 
        int N = arr.length;
 
        int K = 100;
 
        // Initialize dp
        int dp[][] = new int[N + 1][K + 1];
 
        for (int i[] : dp) {
            Arrays.fill(i, -1);
        }
        // Print answer
        System.out.println(maxSum(arr, N, K, dp));
    }
}


Python3
# Python3 program for the
# above approach
 
# Function find the maximum
# sum that doesn't exceeds K
# by choosing elements
def maxSum(a, n, k, dp):
   
    # Base Case
    if (n <= 0):
        return 0;
 
    # Return the memoized state
    if (dp[n][k] != -1):
        return dp[n][k];
 
    # Dont pick the current
    # element
    option = maxSum(a, n - 1,
                    k, dp);
 
    # Pick the current element
    if (k >= a[n - 1]):
        option = max(option, a[n - 1] +
                 maxSum(a, n - 2,
                        k - a[n - 1], dp));
    dp[n][k] = option;
     
    # Return and store
    # the result
    return dp[n][k];
 
# Driver Code
if __name__ == '__main__':
   
    arr = [50, 10, 20,
           30, 40];
    N = len(arr);
    K = 100;
    # Initialize dp
    dp = [[-1 for i in range(K + 1)]
              for j in range(N + 1)]
 
    # Pranswer
    print(maxSum(arr, N,
                 K, dp));
 
# This code is contributed by shikhasingrajput


C#
// C# program for the
// above approach
using System;
class GFG{
 
// Function find the maximum
// sum that doesn't exceeds K
// by choosing elements
public static int maxSum(int []a, int n,
                         int k, int[,] dp)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Return the memoized
  // state
  if (dp[n, k] != -1)
    return dp[n, k];
 
  // Dont pick the current
  // element
  int option = maxSum(a, n - 1,
                      k, dp);
 
  // Pick the current element
  if (k >= a[n - 1])
    option = Math.Max(option, a[n - 1] +
                      maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
  // Return and store the
  // result
  return dp[n, k] = option;
}
 
// Driver Code
public static void Main(String[] args)
{
  int []arr = {50, 10, 20, 30, 40};
  int N = arr.Length;
  int K = 100;
   
  // Initialize dp
  int [,]dp = new int[N + 1,
                      K + 1];
 
  for (int j = 0; j < N + 1; j++)
  {
    for (int k = 0; k < K + 1; k++)
      dp[j, k] = -1;
  }
   
  // Print answer
  Console.WriteLine(maxSum(arr, N,
                           K, dp));
}
}
 
// This code is contributed by Rajput-Ji


Javascript


输出
90

时间复杂度: O(2 N )
辅助空间: O(N)

高效的方法:为了优化上述方法,思想是使用动态规划。每个数组元素都存在两种可能的选项:

  1. 要么跳过当前元素并继续下一个元素。
  2. 仅当当前元素小于或等于K时才选择它。

请按照以下步骤解决问题:

  1. -1初始化数组dp[N][K+1] ,其中dp[i][j]将存储最大总和,以使总和j使用索引i 之前的元素。
  2. 从上面的转换中,如果当前元素被选中,如果没有被选中,递归地找到最大和。
  3. 存储当前状态的最小答案。
  4. 此外,添加基本条件,如果当前状态(i, j)已经被访问,即dp[i][j]!=-1返回dp[i][j]
  5. 打印dp[N][K]作为最大可能和。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Initialize dp
int dp[1005][1005];
 
// Function find the maximum sum that
// doesn't exceeds K by choosing elements
int maxSum(int* a, int n, int k)
{
     
    // Base Case
    if (n <= 0)
        return 0;
 
    // Return the memoized state
    if (dp[n][k] != -1)
        return dp[n][k];
 
    // Dont pick the current element
    int option = maxSum(a, n - 1, k);
 
    // Pick the current element
    if (k >= a[n - 1])
        option = max(option,
                     a[n - 1] +
             maxSum(a, n - 2,
                 k - a[n - 1]));
 
    // Return and store the result
    return dp[n][k] = option;
}
 
// Driver Code
int main()
{
    int N = 5;
 
    int arr[] = { 50, 10, 20, 30, 40 };
 
    int K = 100;
 
    // Fill dp array with -1
    memset(dp, -1, sizeof(dp));
 
    // Print answer
    cout << maxSum(arr, N, K) << endl;
}
 
// This code is contributed by bolliranadheer

Java

// Java program for the above approach
 
import java.util.*;
 
class GFG {
 
    // Function find the maximum sum that
    // doesn't exceeds K by choosing elements
    public static int maxSum(int a[], int n,
                             int k, int[][] dp)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Return the memoized state
        if (dp[n][k] != -1)
            return dp[n][k];
 
        // Dont pick the current element
        int option = maxSum(a, n - 1,
                            k, dp);
 
        // Pick the current element
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
        // Return and store the result
        return dp[n][k] = option;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 50, 10, 20, 30, 40 };
 
        int N = arr.length;
 
        int K = 100;
 
        // Initialize dp
        int dp[][] = new int[N + 1][K + 1];
 
        for (int i[] : dp) {
            Arrays.fill(i, -1);
        }
        // Print answer
        System.out.println(maxSum(arr, N, K, dp));
    }
}

蟒蛇3

# Python3 program for the
# above approach
 
# Function find the maximum
# sum that doesn't exceeds K
# by choosing elements
def maxSum(a, n, k, dp):
   
    # Base Case
    if (n <= 0):
        return 0;
 
    # Return the memoized state
    if (dp[n][k] != -1):
        return dp[n][k];
 
    # Dont pick the current
    # element
    option = maxSum(a, n - 1,
                    k, dp);
 
    # Pick the current element
    if (k >= a[n - 1]):
        option = max(option, a[n - 1] +
                 maxSum(a, n - 2,
                        k - a[n - 1], dp));
    dp[n][k] = option;
     
    # Return and store
    # the result
    return dp[n][k];
 
# Driver Code
if __name__ == '__main__':
   
    arr = [50, 10, 20,
           30, 40];
    N = len(arr);
    K = 100;
    # Initialize dp
    dp = [[-1 for i in range(K + 1)]
              for j in range(N + 1)]
 
    # Pranswer
    print(maxSum(arr, N,
                 K, dp));
 
# This code is contributed by shikhasingrajput

C#

// C# program for the
// above approach
using System;
class GFG{
 
// Function find the maximum
// sum that doesn't exceeds K
// by choosing elements
public static int maxSum(int []a, int n,
                         int k, int[,] dp)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Return the memoized
  // state
  if (dp[n, k] != -1)
    return dp[n, k];
 
  // Dont pick the current
  // element
  int option = maxSum(a, n - 1,
                      k, dp);
 
  // Pick the current element
  if (k >= a[n - 1])
    option = Math.Max(option, a[n - 1] +
                      maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
  // Return and store the
  // result
  return dp[n, k] = option;
}
 
// Driver Code
public static void Main(String[] args)
{
  int []arr = {50, 10, 20, 30, 40};
  int N = arr.Length;
  int K = 100;
   
  // Initialize dp
  int [,]dp = new int[N + 1,
                      K + 1];
 
  for (int j = 0; j < N + 1; j++)
  {
    for (int k = 0; k < K + 1; k++)
      dp[j, k] = -1;
  }
   
  // Print answer
  Console.WriteLine(maxSum(arr, N,
                           K, dp));
}
}
 
// This code is contributed by Rajput-Ji

Javascript


输出
90

时间复杂度: O(N*K),其中 N 是给定数组的大小,K 是限制。
辅助空间: O(N)

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