📌  相关文章
📜  最大化可以根据给定条件组合在一起的数字

📅  最后修改于: 2022-05-13 01:56:06.592000             🧑  作者: Mango

最大化可以根据给定条件组合在一起的数字

给定一个大小为N x 2二维数组A[][] ,其中:

  • 每个元素都位于[1, N] 之间。
  • A[i][0]表示至多必须有严格小于i+1的 A[i][0]个元素和至多严格大于 i+1 的A[i][1] 个元素

任务是找到符合上述条件的最大元素数。

例子:

天真的方法:这个想法是基于这样一个概念,即最少 1 个元素可以保存在一个集合中,并且最多可以将所有元素保存在一起,即N

  • 最初,对于1 <= K <= NK值,检查是否可以按照条件将K个元素组合在一起。
  • N个元素中选择K个元素,并检查从1 到 N的所有K的以下条件。
    • 检查每个候选人i1 到 N
      • 如果C个候选者已经属于K个元素的集合,那么对于 i 个元素属于一组K数, i必须恰好有C个元素小于且KC-1 个元素大于i
    • 通过这种方式,计算有效候选者并检查是否可以将K个元素放在一个集合中。
  • 最后,最大K就是答案。

时间复杂度: O(N 2 )
辅助空间: O(1)

有效的方法:更好的方法是使用二分搜索来解决。

  • 不要检查K的每个可能值,而是在那里使用二分搜索
  • 好像可以将K个元素保持在一起,这意味着也可以将任何较低值的 K 个元素保持在一起。
  • 因此,请检查更高的值,如果无法将K个元素保持在一起,则意味着无法将更高的K值组合在一起。
  • 当较低和较高的价值都成为答案时。

以下是上述方法的实现:

Java
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to check if it is possible
// to keep k elements together
bool isPossible(vector >& a,
                int n, int k)
{
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
        // For i to be a part of the set
        // i's condition must allow to keep
        // Atleast candidatePresent number of
 
        // Elements smaller than i
        // And k-candidatePresent-1
        // Number of elements larger than i
 
        // If so then add i
        // To the set of k numbers
        if (a[i][0] >= candidatePresent
            && a[i][1] >= k - candidatePresent
                              - 1)
            candidatePresent++;
    }
 
    // If possible to keep at lest k
    // elements together return true
    if (candidatePresent >= k)
        return true;
 
    // Else return false
    return false;
}
 
int maxElementsinSet(vector >& a,
                     int n)
{
    int left = 1, right = n;
    int ans = 1;
 
    while (left <= right) {
        int mid = (left + right) / 2;
 
        // If it is possible to keep mid
        // elements together them mid
        // is a possible answer and also
        // check for higher values of mid
        if (isPossible(a, n, mid)) {
            ans = mid;
            left = mid + 1;
        }
 
        // Else check for lower values of mid
        else
            right = mid - 1;
    }
 
    return ans;
}
 
// Driver Code
int main()
{
    int N = 5;
    vector > A = {
        { 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
    };
 
    cout << maxElementsinSet(A, N);
    return 0;
}


Java
// Java code to implement the approach
import java.util.*;
public class GFG {
 
  // Function to check if it is possible
  // to keep k elements together
  static boolean isPossible(int a[][], int n, int k)
  {
 
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
      // For i to be a part of the set
      // i's condition must allow to keep
      // Atleast candidatePresent number of
 
      // Elements smaller than i
      // And k-candidatePresent-1
      // Number of elements larger than i
 
      // If so then add i
      // To the set of k numbers
      if (a[i][0] >= candidatePresent
          && a[i][1] >= k - candidatePresent - 1)
        candidatePresent++;
    }
 
    // If possible to keep at lest k
    // elements together return true
    if (candidatePresent >= k)
      return true;
 
    // Else return false
    return false;
  }
 
  static int maxElementsinSet(int a[][], int n)
  {
    int left = 1, right = n;
    int ans = 1;
 
    while (left <= right) {
      int mid = (left + right) / 2;
 
      // If it is possible to keep mid
      // elements together them mid
      // is a possible answer and also
      // check for highr values of mid
      if (isPossible(a, n, mid) == true) {
        ans = mid;
        left = mid + 1;
      }
 
      // Else check for lower values of mid
      else
        right = mid - 1;
    }
 
    return ans;
  }
 
  // Driver Code
  public static void main(String arg[])
  {
    int N = 5;
    int A[][] = {
      { 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
    };
 
    System.out.println(maxElementsinSet(A, N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Python
# Python code to implement the approach
 
# Function to check if it is possible
# to keep k elements together
def isPossible(a, n, k):
 
    # Initially the set is empty, so
    # candidates present is 0
    candidatePresent = 0
 
    # Loop through all the candidates
    for i in range(n):
 
        # For i to be a part of the set
        # i's condition must allow to keep
        # Atleast candidatePresent number of
 
        # Elements smaller than i
        # And k-candidatePresent-1
        # Number of elements larger than i
 
        # If so then add i
        # To the set of k numbers
        if (a[i][0] >= candidatePresent
            and a[i][1] >= k - candidatePresent
                              - 1):
            candidatePresent += 1
     
 
    # If possible to keep at lest k
    # elements together return true
    if (candidatePresent >= k):
        return 1
 
    # Else return false
    return 0
 
def maxElementsinSet(a, n):
    left = 1
    right = n
    ans = 1
 
    while (left <= right):
        mid = (left + right) / 2
 
        # If it is possible to keep mid
        # elements together them mid
        # is a possible answer and also
        # check for highr values of mid
        if (isPossible(a, n, mid)):
            ans = mid
            left = mid + 1
 
        # Else check for lower values of mid
        else:
            right = mid - 1
 
    print(ans)
 
# Driver Code
if __name__ == "__main__":
   
    N = 5;
    A = [[ 2, 3 ], [ 4, 2 ], [ 3, 1 ], [ 3, 1 ], [ 1, 1 ]]
 
    maxElementsinSet(A, N)
     
    # This code is contributed by hrithikgarg03188.


C#
// C# code to implement the approach
using System;
 
public class GFG {
 
  // Function to check if it is possible
  // to keep k elements together
  static bool isPossible(int[, ] a, int n, int k)
  {
 
    // Initially the set is empty, so
    // candidates present is 0
    int candidatePresent = 0;
 
    // Loop through all the candidates
    for (int i = 0; i < n; i++) {
 
      // For i to be a part of the set
      // i's condition must allow to keep
      // Atleast candidatePresent number of
 
      // Elements smaller than i
      // And k-candidatePresent-1
      // Number of elements larger than i
 
      // If so then add i
      // To the set of k numbers
      if (a[i, 0] >= candidatePresent
          && a[i, 1] >= k - candidatePresent - 1)
        candidatePresent++;
    }
 
    // If possible to keep at lest k
    // elements together return true
    if (candidatePresent >= k)
      return true;
 
    // Else return false
    return false;
  }
 
  static int maxElementsinSet(int[, ] a, int n)
  {
    int left = 1, right = n;
    int ans = 1;
 
    while (left <= right) {
      int mid = (left + right) / 2;
 
      // If it is possible to keep mid
      // elements together them mid
      // is a possible answer and also
      // check for highr values of mid
      if (isPossible(a, n, mid) == true) {
        ans = mid;
        left = mid + 1;
      }
 
      // Else check for lower values of mid
      else
        right = mid - 1;
    }
 
    return ans;
  }
 
  // Driver Code
  public static void Main(String[] arg)
  {
    int N = 5;
    int[, ] A = {
      { 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
    };
 
    Console.WriteLine(maxElementsinSet(A, N));
  }
}
 
// This code is contributed by shikhasingrajput


Javascript


输出
4

时间复杂度: O(N*logN)
辅助空间: O(1)