当一个数组元素可以减半时,总和最多为 K 的最大子集
给定一个大小为N的数组arr[]和一个整数K ,任务是找到最大子集的大小,当只有一个元素可以减半时,总和最多为K (减半的值将四舍五入到最接近的更大整数)。
例子:
Input: arr[] = {4, 4, 5}, K = 15
Output: 3
Explanation: 4+4+5 = 13 which is less than 15. So subset can have all elements.
Input: arr[3] = {2, 3, 5}, K = 9
Output: 3
Explanation: 2 + 3 = 5 which is less than 9
2 + 3 + 5 = 10 which is greater than 9, So cannot be part of subset.
After halving i.e. ceil [5/2] = 3, sum = 2+3+3 = 8 which is less than 9.
So all 3 elements can be part of subset.
Input: arr[8] = {1, 2, 3, 4, 5, 6, 7, 8}, K = 20
Output: 6
Explanation: 1+2+3+4+5 = 15 which is less than 20
15 + 6 = 21 which is greater than 20.
After halving the value i.e. ceil [6/2] = 3
15 + 3 = 18 which is less than 20. So it can be part of subset.
方法:给定的问题可以使用基于以下思想的排序方法来解决:
In a sorted array keep on performing sum from i = 0 to N-1. If at any moment sum is greater than K, that element can only be included if after halving that value the sum is at most K
请按照以下步骤解决问题:
- 按升序对数组进行排序。
- 声明一个变量(比如Sum )来保持总和。
- 从i = 0 到 N-1遍历数组:
- 将arr[i]添加到Sum 。
- 如果Sum大于K ,则使arr[i] = ceil(arr[i]/2)并检查该总和是否小于 K 。
- 如果Sum小于K则继续迭代。
- 增加子集的大小。
- 返回子集的大小。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find total number of element
int findcount(int arr[], int n, int m)
{
int ans = n, sum = 0, count = 0;
// Sort the array
sort(arr, arr + n);
for (int i = 0; i < n; i++) {
// Round up to the ceil value
if (sum + (arr[i] + 1) / 2 > m) {
ans = i;
break;
}
// Sum of the array elements
sum += arr[i];
// Size of the subset
count++;
}
return count;
}
// Driver code
int main()
{
int N = 8, K = 20;
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
// Function call
cout << findcount(arr, N, K);
return 0;
}
Java
// JAVA program for the above approach
import java.util.*;
class GFG {
// Function to find total number of element
public static int findcount(int arr[], int n, int m)
{
int ans = n, sum = 0, count = 0;
// Sort the array
Arrays.sort(arr);
for (int i = 0; i < n; i++) {
// Round up to the ceil value
if (sum + (arr[i] + 1) / 2 > m) {
ans = i;
break;
}
// Sum of the array elements
sum += arr[i];
// Size of the subset
count++;
}
return count;
}
// Driver code
public static void main(String[] args)
{
int N = 8, K = 20;
int arr[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
// Function call
System.out.print(findcount(arr, N, K));
}
}
// This code is contributed by Taranpreet
Python3
# Python solution based on above approach
# Function to find total number of element
def findcount(n, k, arr):
# Sort the array
arr.sort()
sum = 0
count = 0
for i in range(n):
# Round up to the ceil value
if (sum + (arr[i] + 1) / 2 > k):
ans = i
break
# Sum of the array elements
sum += arr[i]
# Size of the subset
count = count + 1
return(count)
# driver code
n = 8
k = 20
arr = [1, 2, 3, 5, 4, 6, 7, 8]
result = findcount(n,k,arr)
print(result)
# This code is contributed by greeshmapslp.
C#
// C# program for the above approach
using System;
class GFG {
// Function to find total number of element
static int findcount(int[] arr, int n, int m)
{
int ans = n, sum = 0, count = 0;
// Sort the array
Array.Sort(arr);
for (int i = 0; i < n; i++) {
// Round up to the ceil value
if (sum + (arr[i] + 1) / 2 > m) {
ans = i;
break;
}
// Sum of the array elements
sum += arr[i];
// Size of the subset
count++;
}
return count;
}
// Driver code
public static void Main()
{
int N = 8, K = 20;
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };
// Function call
Console.Write(findcount(arr, N, K));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
6
时间复杂度: O(N * logN)
辅助空间: O(1)