📜  大小为k的子集的乘积中的最大尾随零数

📅  最后修改于: 2021-04-29 02:18:35             🧑  作者: Mango

给定大小为n的数组和正整数k,请在大小为k的子集的乘积中找到尾随零的最大数量。
例子:

Input : arr = {50, 4, 20}
        k = 2
Output : 3
Here, we have 3 subsets of size 2. [50, 4] 
has product 200, having 2 zeros at the end, 
[4, 20] — product 80, having 1 zero at the 
end, [50, 20] — product 1000, having 3 zeros
at the end. Therefore, the maximum zeros at
the end of the product is 3.

Input : arr = {15, 16, 3, 25, 9}
        k = 3
Output : 3
Here, the subset [15, 16, 25] has product 6000.

Input : arr = {9, 77, 13}
        k = 3
Output : 0
Here, the subset [9, 77, 13] has product 9009
having no zeros at the end.

动态编程方法:
显然,数字结尾处的零数由数字中25的幂的最小值确定。设pw5为最大功率5pw2为最大功率2
假设subset [i] [j]是我们最多可以收集的2s,考虑到每个i中j个数为5s的i个数。
我们遍历给定的所有数字,对于每个数组元素,我们在其中计算2s和5s的数量。令pw2为当前数的2s数,pw5为5s的数。
现在, subset [i] [j]有一个过渡:
//对于当前数字(pw2的两位和pw5的五个),我们检查
//如果我们可以增加subset [i] [j]的值。
子集[i] [j] = max(子集[i] [j],子集[i-1] [j-pw5] + pw2)
上面的表达式也可以写成如下。
子集[i + 1] [j + pw5] = max(子集[i + 1] [j + pw5],子集[i] [j] + pw2);
答案将是max(ans,min(i,subset [k] [i])

C++
// CPP program for finding the maximum number
// of trailing zeros in the product of the
// selected subset of size k.
#include 
using namespace std;
#define MAX5 100
 
// Function to calculate maximum zeros.
int maximumZeros(int* arr, int n, int k)
{
    // Initializing each value with -1;
    int subset[k+1][MAX5+5];   
    memset(subset, -1, sizeof(subset));
 
    subset[0][0] = 0;
 
    for (int p = 0; p < n; p++) {
        int pw2 = 0, pw5 = 0;
 
        // Calculating maximal power of 2 for
        // arr[p].
        while (arr[p] % 2 == 0) {
            pw2++;
            arr[p] /= 2;
        }
 
        // Calculating maximal power of 5 for
        // arr[p].
        while (arr[p] % 5 == 0) {
            pw5++;
            arr[p] /= 5;
        }
 
        // Calculating subset[i][j] for maximum
        // amount of twos we can collect by
        // checking first i numbers and taking
        // j of them with total power of five.
        for (int i = k - 1; i >= 0; i--)
            for (int j = 0; j < MAX5; j++)
 
                // If subset[i][j] is not calculated.
                if (subset[i][j] != -1)
                    subset[i + 1][j + pw5] =
                    max(subset[i + 1][j + pw5],
                         subset[i][j] + pw2);
    }
 
    // Calculating maximal number of zeros.
    // by taking minimum of 5 or 2 and then
    // taking maximum.
    int ans = 0;
    for (int i = 0; i < MAX5; i++)
        ans = max(ans, min(i, subset[k][i]));
 
    return ans;
}
 
// Driver function
int main()
{
    int arr[] = { 50, 4, 20 };
    int k = 2;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maximumZeros(arr, n, k) << endl;
    return 0;
}


Java
import java.util.Arrays;
 
// Java program for finding the maximum number
// of trailing zeros in the product of the
// selected subset of size k.
class GFG {
 
    final static int MAX5 = 100;
 
// Function to calculate maximum zeros.
    static int maximumZeros(int arr[], int n, int k) {
        // Initializing each value with -1;
        int subset[][] = new int[k + 1][MAX5 + 5];
        // Fill each row with 1.0
        for (int[] row : subset) {
            Arrays.fill(row, -1);
        }
        //memset(subset, -1, sizeof(subset));
 
        subset[0][0] = 0;
 
        for (int p = 0; p < n; p++) {
            int pw2 = 0, pw5 = 0;
 
            // Calculating maximal power of 2 for
            // arr[p].
            while (arr[p] % 2 == 0) {
                pw2++;
                arr[p] /= 2;
            }
 
            // Calculating maximal power of 5 for
            // arr[p].
            while (arr[p] % 5 == 0) {
                pw5++;
                arr[p] /= 5;
            }
 
            // Calculating subset[i][j] for maximum
            // amount of twos we can collect by
            // checking first i numbers and taking
            // j of them with total power of five.
            for (int i = k - 1; i >= 0; i--) {
                for (int j = 0; j < MAX5; j++) // If subset[i][j] is not calculated.
                {
                    if (subset[i][j] != -1) {
                        subset[i + 1][j + pw5]
                                = Math.max(subset[i + 1][j + pw5],
                                        subset[i][j] + pw2);
                    }
                }
            }
        }
 
        // Calculating maximal number of zeros.
        // by taking minimum of 5 or 2 and then
        // taking maximum.
        int ans = 0;
        for (int i = 0; i < MAX5; i++) {
            ans = Math.max(ans, Math.min(i, subset[k][i]));
        }
 
        return ans;
    }
 
// Driver function
    public static void main(String[] args) {
        int arr[] = {50, 4, 20};
        int k = 2;
        int n = arr.length;
        System.out.println(maximumZeros(arr, n, k));
 
    }
}
//this code contributed by 29AJayKumar


Python3
# Python3 program for finding the maximum number
# of trailing zeros in the product of the
# selected subset of size k.
MAX5 = 100
 
# Function to calculate maximum zeros.
def maximumZeros(arr, n, k):
    global MAX5
     
    # Initializing each value with -1
    subset = [[-1] * (MAX5 + 5) for _ in range(k + 1)]
 
    subset[0][0] = 0
 
    for p in arr:
         
        pw2, pw5 = 0, 0
 
        # Calculating maximal power
        # of 2 for arr[p].
        while not p % 2 :
            pw2 += 1
            p //= 2
 
        # Calculating maximal power
        # of 5 for arr[p].
        while not p % 5 :
            pw5 += 1
            p //= 5
 
        # Calculating subset[i][j] for maximum
        # amount of twos we can collect by
        # checking first i numbers and taking
        # j of them with total power of five.
        for i in range(k-1, -1, -1):
             
            for j in range(MAX5):
 
                # If subset[i][j] is not calculated.
                if subset[i][j] != -1:
                    subset[i + 1][j + pw5] = (
                        max(subset[i + 1][j + pw5],
                        (subset[i][j] + pw2)))
 
    # Calculating maximal number of zeros.
    # by taking minimum of 5 or 2 and then
    # taking maximum.
    ans = 0
    for i in range(MAX5):
        ans = max(ans, min(i, subset[k][i]))
 
    return ans
 
 
# Driver function
arr = [ 50, 4, 20 ]
k = 2
n = len(arr)
 
print(maximumZeros(arr, n, k))
 
# This code is contributed by Ansu Kumari.


C#
// C# program for finding the maximum number
// of trailing zeros in the product of the
// selected subset of size k.
using System;
public class GFG {
  
static readonly int MAX5 = 100;
// Function to calculate maximum zeros.
    static int maximumZeros(int []arr, int n, int k) {
        // Initializing each value with -1;
        int [,]subset = new int[k + 1,MAX5 + 5];
        // Fill each row with 1.0
        for (int i = 0; i < subset.GetLength(0); i++)
            for (int j = 0; j < subset.GetLength(1); j++)
                subset[i,j] = -1;
 
        subset[0,0] = 0;
  
        for (int p = 0; p < n; p++) {
            int pw2 = 0, pw5 = 0;
  
            // Calculating maximal power of 2 for
            // arr[p].
            while (arr[p] % 2 == 0) {
                pw2++;
                arr[p] /= 2;
            }
  
            // Calculating maximal power of 5 for
            // arr[p].
            while (arr[p] % 5 == 0) {
                pw5++;
                arr[p] /= 5;
            }
  
            // Calculating subset[i][j] for maximum
            // amount of twos we can collect by
            // checking first i numbers and taking
            // j of them with total power of five.
            for (int i = k - 1; i >= 0; i--) {
                for (int j = 0; j < MAX5; j++) // If subset[i][j] is not calculated.
                {
                    if (subset[i,j] != -1) {
                        subset[i + 1,j + pw5]
                                = Math.Max(subset[i + 1,j + pw5],
                                        subset[i,j] + pw2);
                    }
                }
            }
        }
  
        // Calculating maximal number of zeros.
        // by taking minimum of 5 or 2 and then
        // taking maximum.
        int ans = 0;
        for (int i = 0; i < MAX5; i++) {
            ans = Math.Max(ans, Math.Min(i, subset[k,i]));
        }
        return ans;
    }
  
    // Driver function
    public static void Main() {
        int []arr = {50, 4, 20};
        int k = 2;
        int n = arr.Length;
        Console.Write(maximumZeros(arr, n, k));
  
    }
}
//this code contributed by 29AJayKumar


Javascript


输出 :
3