给定大小为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.
动态编程方法:
显然,数字结尾处的零数由数字中2和5的幂的最小值确定。设pw5为最大功率5 , pw2为最大功率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