给定一个由N 个整数和一个整数K组成的数组arr[] ,任务是选择一些最大可能总和不超过K 的非相邻数组元素。
例子:
Input: arr[] = {50, 10, 20, 30, 40}, K = 100
Output: 90
Explanation: To maximize the sum that doesn’t exceed K(= 100), select elements 50 and 40.
Therefore, maximum possible sum = 90.
Input: arr[] = {20, 10, 17, 12, 8, 9}, K = 64
Output: 46
Explanation: To maximize the sum that doesn’t exceed K(= 64), select elements 20, 17, and 9.
Therefore, maximum possible sum = 46.
朴素的方法:最简单的方法是递归生成给定数组的所有可能子集,对于每个子集,检查它是否不包含相邻元素并且总和不超过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)
高效的方法:为了优化上述方法,思想是使用动态规划。每个数组元素都存在两种可能的选项:
- 要么跳过当前元素并继续下一个元素。
- 仅当当前元素小于或等于K时才选择它。
请按照以下步骤解决问题:
- 用-1初始化数组dp[N][K+1] ,其中dp[i][j]将存储最大总和,以使总和j使用索引i 之前的元素。
- 从上面的转换中,如果当前元素被选中,如果没有被选中,递归地找到最大和。
- 存储当前状态的最小答案。
- 此外,添加基本条件,如果当前状态(i, j)已经被访问,即dp[i][j]!=-1返回dp[i][j] 。
- 打印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 现场工作专业课程和学生竞争性编程现场课程。