给定一个由N个整数和一个整数K组成的数组arr [] ,任务是找到给定数组可以分成的不相交子集的最大数量,以使每个子集的最小元素与该子集的大小的乘积。子集至少为K。
例子:
Input: arr[] = {7, 11, 2, 9, 5}, K = 10
Output: 2
Explanation:
All such disjoint subsets possible are:
Subset {11}: Product of minimum and size of the subset = 11 * 1 = 11 ( > 10).
Subset {5, 9, 7}: Product of minimum and size of the subset = 5 * 3 = 15( > 10).
Therefore, the total number of subsets formed is 2.
Input: arr[] = {1, 3, 3, 7}, K = 12
Output: 0
方法:可以根据以下观察值贪婪地解决给定问题:
- 如问题陈述中所述,形成的子集的最小元素与子集的长度的乘积必须至少为K ,因此要使子集的数量最大化,可以将数组的最大元素分组为的最小元素。子集。
- 因此,想法是一一最大化子集的最小元素,从而最大化子集的数量。
请按照以下步骤解决问题:
- 初始化一个变量,例如count为0 ,以存储形成的最大子集数。
- 初始化一个变量,例如将length设置为0 ,以存储子集的长度。
- 按降序对数组进行排序。
- 遍历给定数组arr []并执行以下步骤:
- 将length的值增加1 。
- 如果(arr [i] * length)的值大于K ,则将count的值增加1并将length的值更新为0 。
- 完成上述步骤后,将count的值打印为形成的最大子集数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum number
// of subsets possible such that
// product of their minimums and the
// size of subsets are at least K
int maximumSubset(int arr[], int N,
int K)
{
// Sort the array in
// descending order
sort(arr, arr + N, greater());
// Stores the size of
// the current subset
int len = 0;
// Stores the count of subsets
int ans = 0;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Increment length of the
// subsets by 1
len++;
// If arr[i] * len >= K
if (arr[i] * len >= K) {
// Increment ans by one
ans++;
// Update len
len = 0;
}
}
// Return the maximum possible
// subsets formed
return ans;
}
// Driver Code
int main()
{
int arr[] = { 7, 11, 2, 9, 5 };
int K = 10;
int N = sizeof(arr) / sizeof(arr[0]);
cout << maximumSubset(arr, N, K);
return 0;
}
输出:
2
时间复杂度: O(N * log N)
辅助空间: O(1)