给定由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 to implement
// 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
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
90
时间复杂度: O(2 N )
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是使用动态编程。每个数组元素都有两个可能的选项:
- 要么跳过当前元素,然后继续下一个元素。
- 仅当当前元素小于或等于K时,才选择它。
请按照以下步骤解决问题:
- 用-1初始化数组dp [N] [K + 1] ,其中dp [i] [j]将存储最大和以使用直到索引i的元素构成和j 。
- 从上面的转换中,递归地找到如果当前元素被选择以及如果当前元素未被选择的最大总和。
- 存储当前状态的最小答案。
- 另外,添加一个基本条件,即如果已经访问了当前状态(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));
}
}
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
90
时间复杂度: O(N * K),其中N是给定数组的大小,K是限制。
辅助空间: O(N)