📌  相关文章
📜  从数组中选择元素以使它们的平均值为 K 的方法数

📅  最后修改于: 2021-09-22 09:56:37             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[]和一个整数K 。任务是找到从数组中选择一个或多个元素的方法的数量,使得所选整数的平均值等于给定的数字K

例子:

简单的方法:一个简单的解决方案是尝试所有的可能性,因为 N 可能很大。时间复杂度可以是 2 N
高效的方法:可以通过使用动态规划来优化上述方法来解决这个问题。假设我们在第 i_th 个索引处,并让val为该索引的当前值。我们有两种可能性,要么在答案中选择该元素,要么丢弃该元素。因此,我们现在完成了。我们还将跟踪当前所选元素集中的元素数量。

以下是递归公式。

ways(index, sum, count) 
      = ways(index - 1, sum, count) 
        + ways(index - 1, sum + arr[index], count + 1)

下面是上述方法的实现:

C++
#include 
using namespace std;
 
#define MAX_INDEX 51
#define MAX_SUM 2505
 
// This dp array is used to store our values
// so that we don't have to calculate same
// values again and again
int dp[MAX_INDEX][MAX_SUM][MAX_INDEX];
 
int waysutil(int index, int sum, int count,
             vector& arr, int K)
{
    // Base cases
    // Index can't be less than 0
    if (index < 0)
        return 0;
 
    if (index == 0) {
 
        // No element is picked hence
        // average cannot be calculated
        if (count == 0)
            return 0;
        int remainder = sum % count;
 
        // If remainder is non zero, we cannot
        // divide the sum by count i.e. the average
        // will not be an integer
        if (remainder != 0)
            return 0;
        int average = sum / count;
 
        // If we find an average return 1
        if (average == K)
            return 1;
    }
 
    // If we have already calculated this function
    // simply return it instead of calculating it again
    if (dp[index][sum][count] != -1)
        return dp[index][sum][count];
 
    // If we don't pick the current element
    // simple recur for index -1
    int dontpick = waysutil(index - 1,
                            sum, count, arr, K);
 
    // If we pick the current element add it to
    // our current sum and increment count by 1
    int pick = waysutil(index - 1,
                        sum + arr[index],
                        count + 1, arr, K);
    int total = pick + dontpick;
 
    // Store the value for the current function
    dp[index][sum][count] = total;
    return total;
}
 
// Function to return the number of ways
int ways(int N, int K, int* arr)
{
    vector Arr;
 
    // Push -1 at the beginning to
    // make it 1-based indexing
    Arr.push_back(-1);
    for (int i = 0; i < N; ++i) {
        Arr.push_back(arr[i]);
    }
 
    // Initialize dp array by -1
    memset(dp, -1, sizeof dp);
 
    // Call recursive function
    // waysutil to calculate total ways
    int answer = waysutil(N, 0, 0, Arr, K);
    return answer;
}
 
// Driver code
int main()
{
    int arr[] = { 3, 6, 2, 8, 7, 6, 5, 9 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 5;
    cout << ways(N, K, arr);
 
    return 0;
}


Java
// Java implementation of the above approach
import java.util.*;
 
class GFG
{
 
    static int MAX_INDEX = 51;
    static int MAX_SUM = 2505;
 
    // This dp array is used to store our values
    // so that we don't have to calculate same
    // values again and again
    static int[][][] dp = new int[MAX_INDEX][MAX_SUM][MAX_INDEX];
 
    static int waysutil(int index, int sum, int count,
                        Vector arr, int K)
    {
        // Base cases
        // Index can't be less than 0
        if (index < 0)
        {
            return 0;
        }
 
        if (index == 0)
        {
 
            // No element is picked hence
            // average cannot be calculated
            if (count == 0)
            {
                return 0;
            }
            int remainder = sum % count;
 
            // If remainder is non zero, we cannot
            // divide the sum by count i.e. the average
            // will not be an integer
            if (remainder != 0)
            {
                return 0;
            }
            int average = sum / count;
 
            // If we find an average return 1
            if (average == K)
            {
                return 1;
            }
        }
 
        // If we have already calculated this function
        // simply return it instead of calculating it again
        if (dp[index][sum][count] != -1)
        {
            return dp[index][sum][count];
        }
 
        // If we don't pick the current element
        // simple recur for index -1
        int dontpick = waysutil(index - 1,
                sum, count, arr, K);
 
        // If we pick the current element add it to
        // our current sum and increment count by 1
        int pick = waysutil(index - 1,
                sum + arr.get(index),
                count + 1, arr, K);
        int total = pick + dontpick;
 
        // Store the value for the current function
        dp[index][sum][count] = total;
        return total;
    }
 
    // Function to return the number of ways
    static int ways(int N, int K, int[] arr)
    {
        Vector Arr = new Vector<>();
 
        // Push -1 at the beginning to
        // make it 1-based indexing
        Arr.add(-1);
        for (int i = 0; i < N; ++i)
        {
            Arr.add(arr[i]);
        }
 
        // Initialize dp array by -1
        for (int i = 0; i < MAX_INDEX; i++)
        {
            for (int j = 0; j < MAX_SUM; j++)
            {
                for (int l = 0; l < MAX_INDEX; l++)
                {
                    dp[i][j][l] = -1;
                }
            }
        }
 
        // Call recursive function
        // waysutil to calculate total ways
        int answer = waysutil(N, 0, 0, Arr, K);
        return answer;
    }
 
    // Driver code
    public static void main(String args[])
    {
        int arr[] = {3, 6, 2, 8, 7, 6, 5, 9};
        int N = arr.length;
        int K = 5;
        System.out.println(ways(N, K, arr));
    }
}
 
/* This code contributed by PrinciRaj1992 */


Python3
# Python implementation of above approach
import numpy as np
 
MAX_INDEX = 51
MAX_SUM = 2505
 
# This dp array is used to store our values
# so that we don't have to calculate same
# values again and again
 
# Initialize dp array by -1
dp = np.ones((MAX_INDEX,MAX_SUM,MAX_INDEX)) * -1;
 
def waysutil(index, sum, count, arr, K) :
 
    # Base cases
    # Index can't be less than 0
    if (index < 0) :
        return 0;
 
    if (index == 0) :
 
        # No element is picked hence
        # average cannot be calculated
        if (count == 0) :
            return 0;
             
        remainder = sum % count;
 
        # If remainder is non zero, we cannot
        # divide the sum by count i.e. the average
        # will not be an integer
        if (remainder != 0) :
            return 0;
             
        average = sum // count;
 
        # If we find an average return 1
        if (average == K) :
            return 1;
 
    # If we have already calculated this function
    # simply return it instead of calculating it again
    if (dp[index][sum][count] != -1) :
        return dp[index][sum][count];
 
    # If we don't pick the current element
    # simple recur for index -1
    dontpick = waysutil(index - 1,
                            sum, count, arr, K);
 
    # If we pick the current element add it to
    # our current sum and increment count by 1
    pick = waysutil(index - 1,
                        sum + arr[index],
                        count + 1, arr, K);
                         
    total = pick + dontpick;
 
    # Store the value for the current function
    dp[index][sum][count] = total;
     
    return total;
 
 
# Function to return the number of ways
def ways(N, K, arr) :
 
    Arr = [];
 
    # Push -1 at the beginning to
    # make it 1-based indexing
    Arr.append(-1);
    for i in range(N) :
        Arr.append(arr[i]);
 
    # Call recursive function
    # waysutil to calculate total ways
    answer = waysutil(N, 0, 0, Arr, K);
    return answer;
 
 
# Driver code
if __name__ == "__main__" :
 
    arr = [ 3, 6, 2, 8, 7, 6, 5, 9 ];
    N =len(arr);
    K = 5;
    print(ways(N, K, arr));
 
# This code is contributed by AnkitRai01


C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
     
class GFG
{
 
    static int MAX_INDEX = 51;
    static int MAX_SUM = 2505;
 
    // This dp array is used to store our values
    // so that we don't have to calculate same
    // values again and again
    static int[,,] dp = new int[MAX_INDEX, MAX_SUM, MAX_INDEX];
 
    static int waysutil(int index, int sum, int count,
                        List arr, int K)
    {
        // Base cases
        // Index can't be less than 0
        if (index < 0)
        {
            return 0;
        }
 
        if (index == 0)
        {
 
            // No element is picked hence
            // average cannot be calculated
            if (count == 0)
            {
                return 0;
            }
            int remainder = sum % count;
 
            // If remainder is non zero, we cannot
            // divide the sum by count i.e. the average
            // will not be an integer
            if (remainder != 0)
            {
                return 0;
            }
            int average = sum / count;
 
            // If we find an average return 1
            if (average == K)
            {
                return 1;
            }
        }
 
        // If we have already calculated this function
        // simply return it instead of calculating it again
        if (dp[index,sum,count] != -1)
        {
            return dp[index, sum, count];
        }
 
        // If we don't pick the current element
        // simple recur for index -1
        int dontpick = waysutil(index - 1,
                sum, count, arr, K);
 
        // If we pick the current element add it to
        // our current sum and increment count by 1
        int pick = waysutil(index - 1,
                sum + arr[index],
                count + 1, arr, K);
        int total = pick + dontpick;
 
        // Store the value for the current function
        dp[index,sum,count] = total;
        return total;
    }
 
    // Function to return the number of ways
    static int ways(int N, int K, int[] arr)
    {
        List Arr = new List();
 
        // Push -1 at the beginning to
        // make it 1-based indexing
        Arr.Add(-1);
        for (int i = 0; i < N; ++i)
        {
            Arr.Add(arr[i]);
        }
 
        // Initialize dp array by -1
        for (int i = 0; i < MAX_INDEX; i++)
        {
            for (int j = 0; j < MAX_SUM; j++)
            {
                for (int l = 0; l < MAX_INDEX; l++)
                {
                    dp[i, j, l] = -1;
                }
            }
        }
 
        // Call recursive function
        // waysutil to calculate total ways
        int answer = waysutil(N, 0, 0, Arr, K);
        return answer;
    }
 
    // Driver code
    public static void Main(String []args)
    {
        int []arr = {3, 6, 2, 8, 7, 6, 5, 9};
        int N = arr.Length;
        int K = 5;
        Console.WriteLine(ways(N, K, arr));
    }
}
 
// This code is contributed by Princi Singh


Javascript


输出:
19

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程