给定一个数组nrr [] ,该数组arr []由N个正整数以及整数X和M组成,其中0 <= X
例子:
Input: arr[] = {3, 2, 1, 2}, M = 4, X = 2
Output: 1
Explanation: One of the elements at indices (0-based) 1 or 3 can be removed. If arr[1] is removed, then arr[] modifies to {3, 1, 2} and sum % M = 6 % 4 = 2 which is equal to X = 2.
Input: arr[] = {3, 2, 1, 3}, M = 4, X = 3
Output: 1
Explanation: Remove element arr[1]( = 2). Therefore, arr[] modifies to {3, 1, 3} and sum % M = 7 % 4 = 3 which is equal to X = 3.
天真的方法:最简单的方法是生成给定数组的所有可能子集,对于每个子集,检查除去子集后数组的总和模M是否等于X。如果发现是正确的,请存储其大小。在所有获得的此类子集中打印最小尺寸。
时间复杂度: O(2 N ),其中N是给定数组的长度。
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是基于以下观察结果使用动态编程:
- 如果S%M> X ,则必须从数组中删除总和为S%M – X的最小元素数,以使总和模M等于X。
- 否则,必须删除具有S%M + M – X之和的最小元素数,以使模M和等于X。
请按照以下步骤解决问题:
- 初始化一个dp []表, table [N +1] [X +1] ,其中table [i] [j]表示要删除具有在[0,i]范围内的索引的最小元素数,使得它们的和为j其中X是总和,因此应将其删除。
- 用较大的值为[1,X]范围内的每个i初始化dp [0] [i] 。
- dp转换如下:
dp[i][j] = min(dp[i-1][j], dp[i][j-arr[i-1]]+1)
where, i is in the range [1, N] and j is in the range [1, X].
- 打印dp [N] [X]作为要删除的最小元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum
// elements having sum x
int findSum(vector S, int n, int x)
{
// Initialize dp table
vector > table(n + 1,
vector(
x + 1, 0));
for (int i = 1; i <= x; i++) {
table[0][i] = INT_MAX - 1;
}
// Pre-compute subproblems
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= x; j++) {
// If mod is smaller than element
if (S[i - 1] > j) {
table[i][j] = table[i - 1][j];
}
else {
// Minimum elements with sum
// j upto index i
table[i][j]
= min(table[i - 1][j],
table[i][j
- S[i - 1]]
+ 1);
}
}
}
// Return answer
return (table[n][x] > n)
? -1
: table[n][x];
}
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
void minRemovals(vector arr,
int n, int m, int x)
{
// Sum of all elements
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
// Sum to be removed
int requied_Sum = 0;
if (sum % m < x)
requied_Sum
= m + sum % m - x;
else
requied_Sum
= sum % m - x;
// Print answer
cout << findSum(arr, n,
requied_Sum);
}
// Driver Code
int main()
{
// Given array
vector arr = { 3, 2, 1, 2 };
// Given size
int n = arr.size();
// Given mod and x
int m = 4, x = 2;
// Function call
minRemovals(arr, n, m, x);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the minimum
// elements having sum x
static int findSum(int[] S, int n, int x)
{
// Initialize dp table
int [][]table = new int[n + 1][x + 1];
for(int i = 1; i <= x; i++)
{
table[0][i] = Integer.MAX_VALUE - 1;
}
// Pre-compute subproblems
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= x; j++)
{
// If mod is smaller than element
if (S[i - 1] > j)
{
table[i][j] = table[i - 1][j];
}
else
{
// Minimum elements with sum
// j upto index i
table[i][j] = Math.min(table[i - 1][j],
table[i][j - S[i - 1]] + 1);
}
}
}
// Return answer
return (table[n][x] > n) ? -1 : table[n][x];
}
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
static void minRemovals(int[] arr, int n,
int m, int x)
{
// Sum of all elements
int sum = 0;
for(int i = 0; i < n; i++)
{
sum += arr[i];
}
// Sum to be removed
int requied_Sum = 0;
if (sum % m < x)
requied_Sum = m + sum % m - x;
else
requied_Sum = sum % m - x;
// Print answer
System.out.print(findSum(arr, n,
requied_Sum));
}
// Driver Code
public static void main(String[] args)
{
// Given array
int[] arr = { 3, 2, 1, 2 };
// Given size
int n = arr.length;
// Given mod and x
int m = 4, x = 2;
// Function call
minRemovals(arr, n, m, x);
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program for the above approach
import sys
# Function to find the minimum
# elements having sum x
def findSum(S, n, x):
# Initialize dp table
table = [[0 for x in range(x + 1)]
for y in range(n + 1)]
for i in range(1, x + 1):
table[0][i] = sys.maxsize - 1
# Pre-compute subproblems
for i in range(1, n + 1):
for j in range(1, x + 1):
# If mod is smaller than element
if (S[i - 1] > j):
table[i][j] = table[i - 1][j]
else:
# Minimum elements with sum
# j upto index i
table[i][j] = min(table[i - 1][j],
table[i][j - S[i - 1]] + 1)
# Return answer
if (table[n][x] > n):
return -1
return table[n][x]
# Function to find minimum number
# of removals to make sum % M in
# remaining array is equal to X
def minRemovals(arr, n, m, x):
# Sum of all elements
sum = 0
for i in range(n):
sum += arr[i]
# Sum to be removed
requied_Sum = 0
if (sum % m < x):
requied_Sum = m + sum % m - x
else:
requied_Sum = sum % m - x
# Print answer
print(findSum(arr, n,
requied_Sum))
# Driver Code
if __name__ == "__main__":
# Given array
arr = [ 3, 2, 1, 2 ]
# Given size
n = len(arr)
# Given mod and x
m = 4
x = 2
# Function call
minRemovals(arr, n, m, x)
# This code is contributed by chitranayal
C#
// C# program for the
// above approach
using System;
class GFG{
// Function to find the minimum
// elements having sum x
static int findSum(int[] S,
int n, int x)
{
// Initialize dp table
int [,]table = new int[n + 1,
x + 1];
for(int i = 1; i <= x; i++)
{
table[0, i] = int.MaxValue - 1;
}
// Pre-compute subproblems
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= x; j++)
{
// If mod is smaller than
// element
if (S[i - 1] > j)
{
table[i, j] = table[i - 1, j];
}
else
{
// Minimum elements with sum
// j upto index i
table[i, j] = Math.Min(table[i - 1, j],
table[i, j -
S[i - 1]] + 1);
}
}
}
// Return answer
return (table[n, x] > n) ? -1 :
table[n, x];
}
// Function to find minimum number
// of removals to make sum % M in
// remaining array is equal to X
static void minRemovals(int[] arr, int n,
int m, int x)
{
// Sum of all elements
int sum = 0;
for(int i = 0; i < n; i++)
{
sum += arr[i];
}
// Sum to be removed
int requied_Sum = 0;
if (sum % m < x)
requied_Sum = m + sum %
m - x;
else
requied_Sum = sum % m - x;
// Print answer
Console.Write(findSum(arr, n,
requied_Sum));
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int[] arr = {3, 2, 1, 2};
// Given size
int n = arr.Length;
// Given mod and x
int m = 4, x = 2;
// Function call
minRemovals(arr, n, m, x);
}
}
// This code is contributed by Amit Katiyar
1
时间复杂度: O(N * X),其中N是给定数组的长度,X是给定整数。
辅助空间: O(N * X)