📌  相关文章
📜  索引子集的计数,使得 A 中这些索引的最大值至少是 B 的总和

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

索引子集的计数,使得 A 中这些索引的最大值至少是 B 的总和

给定两个由N个正整数组成的数组A[]B[] ,任务是找到索引子集的总数,使得数组A[]中所有这些索引的最大值大于或等于数组B[]中这些索引的所有值的总和。

例子:

方法:上述问题可以通过动态规划的帮助下使用子集和问题中讨论的概念来解决。这个想法是创建一个维度为N *数组 A[] 的最大元素的dp[][ ] 。现在, dp[][]矩阵的每个节点,即dp[i][j]表示具有和j的前i个元素的子集的数量。请按照以下步骤解决此问题:

  • 创建一个变量,例如 0存储所需子集的总数。
  • 创建一个成对向量,比如AB ,并用 A 和 B 的元素填充它,即AB[i] = {A[i], B[i]}
  • 根据第一个元素对这个向量对进行排序。
  • 最初 dp 表将用零填充,除了dp[0][0] = 1
  • 遍历数组AB[]并将AB[i].first的值视为最大值,因为AB在第一个元素上排序,并且在[0, i]范围内为最大值,并且在每次迭代中,遍历所有可能的和j并且对于每次迭代计算子集,直到索引i通过包含和排除当前元素而具有总和j
  • 完成上述步骤后,遍历矩阵dp[][]并通过检查以下条件检查形成的子集有多少是有效的。如果发现为,则将值dp[i – 1][j]添加到变量ans中。
  • 完成上述步骤后,打印ans的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the number of non-empty
// subset of indices such that the maximum
// of values over these indices in A is
// at least the total sum over B[]
int countValidSubsets(int A[], int B[], int N)
{
    int ans = 0;
 
    vector > AB(N);
 
    // Stores the maximum element in
    // the array A[]
    int mx = INT_MIN;
 
    // Do the DP in 1-based indexing
    // as there will be no corner case
    // to handle specifically
    for (int i = 0; i <= N; i++) {
        AB[i] = { A[i], B[i] };
        mx = max(mx, A[i]);
    }
 
    // Sort the pair vector
    sort(AB.begin(), AB.end());
 
    // dp matrix where dp[i][j] denotes
    // total valid subsets upto index
    // i with sum j
    vector > dp(
        N + 1, vector(mx + 1, 0));
 
    dp[0][0] = 1;
 
    // Traverse the array AB[]
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= mx; j++) {
 
            // Selecting the current
            // element in the subset
            if (j + AB[i - 1].second <= mx) {
                dp[i][j + AB[i - 1].second]
                    += dp[i - 1][j];
            }
 
            // Discarding the element
            dp[i][j] += dp[i - 1][j];
        }
    }
 
    // Take the count of valid subsets
    for (int i = 1; i <= N; ++i) {
        int cnt = 0;
 
        // Iterate through all the
        // possible subsets
        for (int j = 0; j <= mx; j++) {
 
            // Check if the current subsets
            // till index i having sum j
            // are valid
            if (j + AB[i - 1].second
                <= AB[i - 1].first) {
                cnt += dp[i - 1][j];
            }
        }
 
        // Update the value of ans
        ans += cnt;
    }
 
    // Return the total count of subsets
    return ans;
}
 
// Driver Code
int main()
{
    int A[] = { 1, 3, 2, 6 };
    int B[] = { 7, 3, 2, 1 };
    int N = sizeof(A) / sizeof(A[0]);
 
    cout << countValidSubsets(A, B, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Function to find the number of non-empty
// subset of indices such that the maximum
// of values over these indices in A is
// at least the total sum over B[]
static int countValidSubsets(int A[], int B[], int N)
{
    int ans = 0;
 
    pair []AB = new pair[N];
 
    // Stores the maximum element in
    // the array A[]
    int mx = Integer.MIN_VALUE;
 
    // Do the DP in 1-based indexing
    // as there will be no corner case
    // to handle specifically
    for (int i = 0; i < N; i++) {
        AB[i] = new pair( A[i], B[i] );
        mx = Math.max(mx, A[i]);
    }
 
    // Sort the pair vector
    Arrays.sort(AB,(a,b)->a.first-b.first);
 
    // dp matrix where dp[i][j] denotes
    // total valid subsets upto index
    // i with sum j
    int[][] dp= new int[N + 1][mx + 1];
 
    dp[0][0] = 1;
 
    // Traverse the array AB[]
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= mx; j++) {
 
            // Selecting the current
            // element in the subset
            if (j + AB[i - 1].second <= mx) {
                dp[i][j + AB[i - 1].second]
                    += dp[i - 1][j];
            }
 
            // Discarding the element
            dp[i][j] += dp[i - 1][j];
        }
    }
 
    // Take the count of valid subsets
    for (int i = 1; i <= N; ++i) {
        int cnt = 0;
 
        // Iterate through all the
        // possible subsets
        for (int j = 0; j <= mx; j++) {
 
            // Check if the current subsets
            // till index i having sum j
            // are valid
            if (j + AB[i - 1].second
                <= AB[i - 1].first) {
                cnt += dp[i - 1][j];
            }
        }
 
        // Update the value of ans
        ans += cnt;
    }
 
    // Return the total count of subsets
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    int A[] = { 1, 3, 2, 6 };
    int B[] = { 7, 3, 2, 1 };
    int N = A.length;
 
    System.out.print(countValidSubsets(A, B, N));
 
}
}
 
// This code is contributed by shikhasingrajput


Python3
# python program for the above approach
INT_MIN = -2147483648
 
# Function to find the number of non-empty
# subset of indices such that the maximum
# of values over these indices in A is
# at least the total sum over B[]
def countValidSubsets(A, B, N):
    ans = 0
    AB = [[0 for _ in range(2)] for _ in range(N)]
 
    # Stores the maximum element in
    # the array A[]
    mx = INT_MIN
 
    # Do the DP in 1-based indexing
    # as there will be no corner case
    # to handle specifically
    for i in range(0, N):
        AB[i] = [A[i], B[i]]
        mx = max(mx, A[i])
 
        # Sort the pair vector
    AB.sort()
 
    # dp matrix where dp[i][j] denotes
    # total valid subsets upto index
    # i with sum j
    dp = [[0 for _ in range(mx+1)] for _ in range(N+1)]
 
    dp[0][0] = 1
 
    # Traverse the array AB[]
    for i in range(1, N+1):
        for j in range(0, mx+1):
 
                        # Selecting the current
                        # element in the subset
            if (j + AB[i - 1][1] <= mx):
                dp[i][j + AB[i - 1][1]] += dp[i - 1][j]
 
                # Discarding the element
            dp[i][j] += dp[i - 1][j]
 
        # Take the count of valid subsets
    for i in range(1, N+1):
        cnt = 0
 
        # Iterate through all the
        # possible subsets
        for j in range(0, mx+1):
 
                        # Check if the current subsets
                        # till index i having sum j
                        # are valid
            if (j + AB[i - 1][1] <= AB[i - 1][0]):
                cnt += dp[i - 1][j]
 
                # Update the value of ans
        ans += cnt
 
        # Return the total count of subsets
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    A = [1, 3, 2, 6]
    B = [7, 3, 2, 1]
    N = len(A)
 
    print(countValidSubsets(A, B, N))
 
    # This code is contributed by rakeshsahni


C#
// C# program for the above approach
using System;
using System.Linq;
public class GFG{
    class pair : IComparable
    {
        public int first, second;
        public pair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
         public int CompareTo(pair p)
         {
             return this.first-p.second;
         }
    }
   
// Function to find the number of non-empty
// subset of indices such that the maximum
// of values over these indices in A is
// at least the total sum over []B
static int countValidSubsets(int []A, int []B, int N)
{
    int ans = 0;
 
    pair []AB = new pair[N];
 
    // Stores the maximum element in
    // the array []A
    int mx = int.MinValue;
 
    // Do the DP in 1-based indexing
    // as there will be no corner case
    // to handle specifically
    for (int i = 0; i < N; i++) {
        AB[i] = new pair( A[i], B[i] );
        mx = Math.Max(mx, A[i]);
    }
 
    // Sort the pair vector
    Array.Sort(AB);
    AB.Reverse();
 
 
    // dp matrix where dp[i,j] denotes
    // total valid subsets upto index
    // i with sum j
    int[,] dp= new int[N + 1,mx + 1];
 
    dp[0,0] = 1;
 
    // Traverse the array AB[]
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= mx; j++) {
 
            // Selecting the current
            // element in the subset
            if (j + AB[i - 1].second <= mx) {
                dp[i,j + AB[i - 1].second]
                    += dp[i - 1,j];
            }
 
            // Discarding the element
            dp[i,j] += dp[i - 1,j];
        }
    }
 
    // Take the count of valid subsets
    for (int i = 1; i <= N; ++i) {
        int cnt = 0;
 
        // Iterate through all the
        // possible subsets
        for (int j = 0; j <= mx; j++) {
 
            // Check if the current subsets
            // till index i having sum j
            // are valid
            if (j + AB[i - 1].second
                <= AB[i - 1].first) {
                cnt += dp[i - 1,j];
            }
        }
 
        // Update the value of ans
        ans += cnt;
    }
 
    // Return the total count of subsets
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []A = { 1, 3, 2, 6 };
    int []B = { 7, 3, 2, 1 };
    int N = A.Length;
 
    Console.Write(countValidSubsets(A, B, N));
 
}
}
 
// This code contributed by shikhasingrajput


Javascript


输出:
6

时间复杂度: O(N*M),其中 M 是数组中的最大元素
辅助空间: O(N*M)