给定一个整数V和一个由N 个整数组成的数组arr[] ,任务是找到可以从数组arr[] 中选择的最大数组元素数,以获得总和V 。每个数组元素可以被选择任意次数。如果无法获得总和,则打印-1 。
例子:
Input: arr[] = {25, 10, 5}, V = 30
Output: 6
Explanation:
To obtain sum 30, select arr[2] (= 5), 6 times.
Therefore, the count is 6.
Input: arr[] = {9, 6, 4, 3}, V = 11
Output: 3
Explanation:
To obtain sum 11, possible combinations is : 4,4,3
Therefore, the count is 3
朴素的方法:最简单的方法是使用索引0到j的数组元素递归地找到生成总和V 的数组元素的最大数量,然后使用索引0到i的元素找到生成V所需的最大元素数量,其中j <我 < N 。完成上述步骤后,打印获得给定总和V所需的数组元素计数。
时间复杂度: O(V N )
辅助空间: O(N)
高效的方法:为了优化上述方法,思想是使用动态规划。请按照以下步骤解决问题:
- 初始化一个大小为V + 1的数组table[] ,其中table[i]将存储最优解以获得总和i 。
- 使用-1初始化table[]和使用0初始化table[ 0]作为0数组元素需要获得值0 。
- 对于从i = 0 到 V 的每个值,计算以下 DP 转换所需的数组元素的最大数量:
table[i] = Max(table[i – arr[j]], table[i]), Where table[i-arr[j]]!=-1
where 1 ≤ i ≤ V and 0 ≤ j ≤ N
- 完成上述步骤后,打印表[V]的值,这是要求的答案。
下面是上述方法的实现:
C++14
// C++14 program for the above approach
#include
using namespace std;
// Function that count the maximum
// number of elements to obtain sum V
int maxCount(vector arr, int m, int V)
{
// Stores the maximum number of
// elements required to obtain V
vector table(V + 1);
// Base Case
table[0] = 0;
// Initialize all table values
// as Infinite
for (int i = 1; i <= V; i++)
table[i] = -1;
// Find the max arr required
// for all values from 1 to V
for (int i = 1; i <= V; i++) {
// Go through all arr
// smaller than i
for (int j = 0; j < m; j++) {
// If current coin value
// is less than i
if (arr[j] <= i) {
int sub_res = table[i - arr[j]];
// Update table[i]
if (sub_res != -1 && sub_res + 1 > table[i])
table[i] = sub_res + 1;
}
}
}
// Return the final count
return table[V];
}
// Driver Code
int main()
{
// Given array
vector arr = { 25, 10, 5 };
int m = arr.size();
// Given sum V
int V = 30;
// Function call
cout << (maxCount(arr, m, V));
return 0;
}
// This code is contributed by mohit kumar 29
Java
// Java program for the above approach
import java.io.*;
class GFG {
// Function that count the maximum
// number of elements to obtain sum V
static int maxCount(int arr[], int m, int V)
{
// Stores the maximum number of
// elements required to obtain V
int table[] = new int[V + 1];
// Base Case
table[0] = 0;
// Initialize all table values
// as Infinite
for (int i = 1; i <= V; i++)
table[i] = -1;
// Find the max arr required
// for all values from 1 to V
for (int i = 1; i <= V; i++) {
// Go through all arr
// smaller than i
for (int j = 0; j < m; j++) {
// If current coin value
// is less than i
if (arr[j] <= i) {
int sub_res = table[i - arr[j]];
// Update table[i]
if (sub_res != -1
&& sub_res + 1 > table[i])
table[i] = sub_res + 1;
}
}
}
// Return the final count
return table[V];
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 25, 10, 5 };
int m = arr.length;
// Given sum V
int V = 30;
// Function Call
System.out.println(maxCount(arr, m, V));
}
}
Python3
# Python program for the
# above approach
# Function that count
# the maximum number of
# elements to obtain sum V
def maxCount(arr, m, V):
'''
You can assume array elements as domination
which are provided to you in infinite quantity
just like in coin change problem.
I made a small change in logic on coin change
problem (minimum number of coins required).
There we use to take min(table[i-arr[j]]+1,table[i]),
here min is changed with max function.
Dry run:
assume : taget = 10, arr = [2,3,5]
table 0 1 2 3 4 5 6 7 8 9 10
0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
taking first domination = 2
table 0 1 2 3 4 5 6 7 8 9 10
0 -1 1 -1 2 -1 3 -1 4 -1 5
taking second domination = 3
table 0 1 2 3 4 5 6 7 8 9 10
0 -1 1 1 2 -1 3 -1 4 3 5
here for i = 6 we have max(table[i-dom]+1,table[i])
hence
=> max(tabel[6-3]+1,tabel[6])
=> max(2,3) => 3
taking third domination = 5
table 0 1 2 3 4 5 6 7 8 9 10
0 -1 1 1 2 1 3 -1 4 3 5
Hence total 5 coins are required (2,2,2,2,2)
'''
# Stores the maximum
# number of elements
# required to obtain V
table = [0 for i in range(V+1)]
# Base Case
table[0] = 0
# Initialize all table
# values as Infinite
for i in range(1, V + 1, 1):
table[i] = -1
# Find the max arr required
# for all values from 1 to V
for i in range(1, V + 1, 1):
# Go through all arr
# smaller than i
for j in range(0, m, 1):
# If current coin value
# is less than i
if (arr[j] <= i):
sub_res = table[i - arr[j]]
# Update table[i]
if (sub_res != -1 and
sub_res + 1 > table[i]):
table[i] = sub_res + 1
# Return the final count
return table[V]
# Driver Code
if __name__ == '__main__':
# Given array
arr = [25, 10, 5]
m = len(arr)
# Given sum V
V = 30
# Function Call
print(f'Maximum number of array elements required :
{maxCount(arr, m, V)}')
# This code is contributed by Aaryaman Sharma
C#
// C# program for the
// above approach
using System;
class GFG{
// Function that count the
// maximum number of elements
// to obtain sum V
static int maxCount(int[] arr,
int m, int V)
{
// Stores the maximum number of
// elements required to obtain V
int[] table = new int[V + 1];
// Base Case
table[0] = 0;
// Initialize all table
// values as Infinite
for (int i = 1; i <= V; i++)
table[i] = -1;
// Find the max arr required
// for all values from 1 to V
for (int i = 1; i <= V; i++)
{
// Go through all arr
// smaller than i
for (int j = 0; j < m; j++)
{
// If current coin value
// is less than i
if (arr[j] <= i)
{
int sub_res = table[i - arr[j]];
// Update table[i]
if (sub_res != -1 &&
sub_res + 1 > table[i])
table[i] = sub_res + 1;
}
}
}
// Return the final count
return table[V];
}
// Driver code
static void Main()
{
// Given array
int[] arr = {25, 10, 5};
int m = arr.Length;
// Given sum V
int V = 30;
// Function Call
Console.WriteLine(maxCount(arr,
m, V));
}
}
// This code is contributed by divyeshrabadiya07
Javascript
6
时间复杂度: O(N * V)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。