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

📅  最后修改于: 2021-04-26 18:22:13             🧑  作者: Mango

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

例子:

简单方法:一个简单的解决方案是尝试所有可能性,因为N可以很大。时间复杂度可以是2 N。

高效方法:可以通过使用动态编程来解决上述问题,从而优化上述方法。假设我们在第i_个索引处,令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


输出:
19