Minimizing Total Cost for MEX Reduction
Last Updated :
09 Jan, 2024
Given an array A[] of N integers perform the following operation till the MEX (Minimum Excluded Element) of the array is greater than 0: Pick any element of the array and remove it from the array. This operation costs MEX (A) i.e., MEX of the array A[], after removing the element. The task is to minimize Total Cost to reduce the MEX of the final array to 0.
Examples:
Input: A = [1, 0, 2, 2, 0]
Output: 2
Explanation:
- Remove 1, array becomes [0, 2, 2, 0], add MEX (a)=1 to total cost.
- Remove 0, array becomes [ 2, 2, 0], add MEX (a)=1 to total cost.
- Remove 0, array becomes [ 2, 2], add MEX (a)=0 to total cost. Now removing any element won’t increase the total cost so, minimum total score will be 2.
Input: A = [1, 2, 2, 3]
Output: 0
Explanation: As MEX of the array is already 0, removing any element won’t change the total cost.
Approach: The problem can be solved using the following approach:
The idea is to apply operations till MEX is greater than 0, because if MEX becomes 0, then total Cost won’t be changed. Till MEX(A) doesn’t become 0, we can pick any integer j, such that j<MEX(A) and delete all occurrence of j, then MEX (a) becomes j. We can apply Dynamic Programming, dp[i] represents the minimum total cost to reduce MEX of the array from i to 0.
dp[i]=min(dp[i], dp[j] + (count(j) – 1) * i + j), for all j from 0 to i-1 and count(j) is the number of occurrences of j in array a.
Follow the steps to solve the problem:
- Initialize a frequency array
freq
to count the occurrences of each element in the input array a
. The frequency is counted only for elements less than n
.
- Identify the MEX by finding the first element with a frequency of 0 in the frequency array. This MEX value is crucial for the Dynamic Programming approach.
- Initialize the dp array of size where dp[i] represents the minimum total cost to reduce MEX of the array from i to 0.
- dp[i] can be calculated by:
- Iterate j from 0 to i-1,
- dp[i]=min(dp[i], dp[j] + (count(j) – 1) * i + j)
- The base case of the recursion is when the MEX is already 0, and in such cases, the cost is 0. If the result for a specific MEX has already been calculated (
vis[mex] == 1
), it is retrieved from the memoized array (dp
)
- Minimum Total Cost will be stored in dp[mex], where mex is the MEX of original array.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int memo(vector< int >& freq, vector< int >& dp,
vector< int >& vis, int mex)
{
if (mex == 0)
return 0;
if (vis[mex] == 1) {
return dp[mex];
}
int ans = 1e9;
for ( int i = 0; i < mex; i++) {
ans = min(ans, (freq[i] - 1) * mex + i
+ memo(freq, dp, vis, i));
}
dp[mex] = ans;
vis[mex] = 1;
return dp[mex];
}
void solve(vector< int >& A, int n)
{
vector< int > freq(n, 0);
for ( int i = 0; i < n; i++) {
cin >> A[i];
if (A[i] < n)
freq[A[i]]++;
}
int mex = 0;
for ( int i = 0; i <= n; i++) {
if (freq[i] == 0) {
mex = i;
break ;
}
}
vector< int > dp(mex + 1, 0);
vector< int > vis(mex + 1, 0);
cout << memo(freq, dp, vis, mex) << "\n" ;
}
int main()
{
int n = 5;
vector< int > A = { 1, 0, 2, 2, 0 };
solve(A, n);
}
|
Java
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int memo( int [] freq, int [] dp, int [] vis, int mex) {
if (mex == 0 )
return 0 ;
if (vis[mex] == 1 ) {
return dp[mex];
}
int ans = Integer.MAX_VALUE;
for ( int i = 0 ; i < mex; i++) {
ans = Math.min(ans, (freq[i] - 1 ) * mex + i
+ memo(freq, dp, vis, i));
}
dp[mex] = ans;
vis[mex] = 1 ;
return dp[mex];
}
static void solve( int [] A, int n) {
int [] freq = new int [n];
for ( int i = 0 ; i < n; i++) {
if (A[i] < n)
freq[A[i]]++;
}
int mex = 0 ;
for ( int i = 0 ; i <= n; i++) {
if (freq[i] == 0 ) {
mex = i;
break ;
}
}
int [] dp = new int [mex + 1 ];
int [] vis = new int [mex + 1 ];
Arrays.fill(vis, 0 );
System.out.println(memo(freq, dp, vis, mex));
}
public static void main(String[] args) {
int n = 5 ;
int [] A = { 1 , 0 , 2 , 2 , 0 };
solve(A, n);
}
}
|
Python3
def memo(freq, dp, vis, mex):
if mex = = 0 :
return 0
if vis[mex] = = 1 :
return dp[mex]
ans = float ( 'inf' )
for i in range (mex):
ans = min (ans, (freq[i] - 1 ) * mex + i + memo(freq, dp, vis, i))
dp[mex] = ans
vis[mex] = 1
return dp[mex]
def solve(A, n):
freq = [ 0 ] * n
for i in range (n):
if A[i] < n:
freq[A[i]] + = 1
mex = 0
for i in range (n + 1 ):
if freq[i] = = 0 :
mex = i
break
dp = [ 0 ] * (mex + 1 )
vis = [ 0 ] * (mex + 1 )
print (memo(freq, dp, vis, mex))
if __name__ = = "__main__" :
n = 5
A = [ 1 , 0 , 2 , 2 , 0 ]
solve(A, n)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int Memo(List< int > freq, List< int > dp, List< int > vis, int mex)
{
if (mex == 0)
return 0;
if (vis[mex] == 1)
{
return dp[mex];
}
int ans = int .MaxValue;
for ( int i = 0; i < mex; i++)
{
ans = Math.Min(ans, (freq[i] - 1) * mex + i + Memo(freq, dp, vis, i));
}
dp[mex] = ans;
vis[mex] = 1;
return dp[mex];
}
static void Solve(List< int > A, int n)
{
List< int > freq = new List< int >( new int [n]);
for ( int i = 0; i < n; i++)
{
if (A[i] < n)
freq[A[i]]++;
}
int mex = 0;
for ( int i = 0; i <= n; i++)
{
if (freq[i] == 0)
{
mex = i;
break ;
}
}
List< int > dp = new List< int >( new int [mex + 1]);
List< int > vis = new List< int >( new int [mex + 1]);
Console.WriteLine(Memo(freq, dp, vis, mex));
}
static void Main()
{
int n = 5;
List< int > A = new List< int > { 1, 0, 2, 2, 0 };
Solve(A, n);
}
}
|
Javascript
function memo(freq, dp, vis, mex) {
if (mex === 0)
return 0;
if (vis[mex] === 1) {
return dp[mex];
}
let ans = 1e9;
for (let i = 0; i < mex; i++) {
ans = Math.min(ans, (freq[i] - 1) * mex + i + memo(freq, dp, vis, i));
}
dp[mex] = ans;
vis[mex] = 1;
return dp[mex];
}
function solve(A, n) {
let freq = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
if (A[i] < n)
freq[A[i]]++;
}
let mex = 0;
for (let i = 0; i <= n; i++) {
if (freq[i] === 0) {
mex = i;
break ;
}
}
let dp = new Array(mex + 1).fill(0);
let vis = new Array(mex + 1).fill(0);
console.log(memo(freq, dp, vis, mex));
}
function main() {
let n = 5;
let A = [1, 0, 2, 2, 0];
solve(A, n);
}
main();
|
Time Complexity: O(N2), where N is the number of elements in the input array A[].
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...