There are n cores of processor. Each core can process a task at a time. Different cores can process different tasks simultaneously without affecting others. Suppose, there are m tasks in queue and the processor has to process these m tasks. Again, these m tasks are not all of similar type. The type of task is denoted by a number. So, m tasks are represented as m consecutive numbers, same number represents same type of task, like 1 represents task of type 1, 2 for type 2 task and so on.
Initially, all the cores are free. It takes one unit of cost to start a type of task in a core, which is currently not running in that core. One unit cost will be charged at the starting to start tasks on each core. As an example, a core is running type 3 task and if we assign type 3 task again in that core, then cost for this assignment will be zero. But, if we assign type 2 task then cost for this assignment will be one unit. A core keeps processing a task until next task is assigned to that core.
Example :
Input : n = 3, m = 6, arr = {1, 2, 1, 3, 4, 1}
Output : 4
Input : n = 2, m = 6, arr = {1, 2, 1, 3, 2, 1}
Output : 4
Input : n = 3, m = 31,
arr = {7, 11, 17, 10, 7, 10, 2, 9, 2, 18, 8, 10, 20, 10, 3, 20,
17, 17, 17, 1, 15, 10, 8, 3, 3, 18, 13, 2, 10, 10, 11}
Output : 18
Explanation (for 1st sample I/O) :
Here total number of cores are 3. Let, A, B and C. First assign task of type 1 in any of the cores -> cost 1 unit. States: A – 1, B – None, C – None. Assign task of type 2 in any of the rest 2 cores -> cost 1 unit. States : A – 1, B – 2, C – None. Then assign task of type 1 in that core where task of type 1 is ongoing -> cost 0 unit. States : A – 1, B – 2, C – None.
Assign task of type 3 in the free core -> cost 1 unit. States : A – 1, B – 2, C – 3.
Now, all the cores are running a task. So we have to assign task of type 4 in one of these cores. Let’s load it in the core B, where previously type 2 task was going on -> cost 1 unit.
States: A – 1, B – 4, C – 3. Now, load the type 1 task in the core A, where type 1 task is running -> cost 0 unit. States: A – 1, B – 4, C – 3. Hence, total cost = 1 + 1 + 0 + 1 + 1 + 0 = 4 units.
Explanation 2 (for 2nd sample I/O) :
Total number of cores are 2. Let A and B. First process task of type 1 in any of the cores -> cost 1 unit. States: A – 1, B – None.
Process task of type 2 in any of the rest 2 cores -> cost 1 unit. States: A – 1, B – 2. Then process task of type 1 in that core where task of type 1 is ongoing -> cost 0 unit. States : A – 1, B – 2. Now, let’s assign task of type 3 to core A -> cost 1 unit. States : A – 3, B – 2.
Now, assign type 2 task in core B, where already type 2 task is going on -> cost 0 unit. States : A – 3, B – 2. Hence, total cost = 1 + 1 + 0 + 1 + 1 = 4 unit. Last assign type 1 task in any of the cores(say A) -> cost 1 unit. States : A – 1, B – 2. Hence, total cost = 1 + 1 + 0 + 1 + 0 + 1 = 4 units.
Approach :
Dividing this problem into two cases :
First one is when same type of task is currently running in one of the cores. Then, just assign the upcoming task to that core. For example 1, at i = 3(third task), when type 1 task comes then we can assign that task to that core where previously type 1 task was going on. Cost of this is 0 unit.
Second case is when the same type of task is not running in any of the cores. Then, there may be two possibilities. Sub-case 1 is, if there is at least one free core then assign the upcoming task to that core.
Sub-case 2 is, if there are no free core then we have to stop processing one type of task, free up a core and assign the upcoming task in that core such that the cost in future becomes minimum. To minimize cost we should stop one type of task which will never occur again in future. If every ongoing task reoccurs at least once in future, then we should stop that task which will reoccur last among all the currently ongoing tasks(it is a greedy approach and will task).
For example 2 : at i = 4(fourth task), type 3 task, currently ongoing type 1 and type 2 tasks in two cores, we can stop task type 1 or task type 2 to start task type 3. But we will stop task type 1 as type 1 task rehappens after type two task.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int find(vector< int > arr, int pos,
int m, vector< bool > isRunning)
{
vector< int > d(m + 1, 0);
for ( int i = m; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
int maxipos = 0;
for ( int ele : d)
maxipos = max(ele, maxipos);
return maxipos;
}
int mincost( int n, int m, vector< int > arr)
{
vector<vector< int > > freqarr(m);
vector< int > newvec(m + 1, 0);
freqarr[m - 1] = newvec;
for ( int i = m - 2; i >= 0; i--)
{
vector< int > nv;
nv = freqarr[i + 1];
nv[arr[i + 1]] += 1;
freqarr[i] = nv;
}
vector< bool > isRunning(m + 1, false );
int cost = 0;
int truecount = 0;
for ( int i = 0; i < m; i++) {
int ele = arr[i];
if (isRunning[ele] == true )
continue ;
else {
if (truecount < n) {
cost += 1;
truecount += 1;
isRunning[ele] = true ;
}
else {
int mini = 100000;
int miniind = 0;
for ( int j = 1; j <= m; j++) {
if (isRunning[j] && mini > freqarr[i][j]) {
mini = freqarr[i][j];
miniind = j;
}
}
if (mini == 0) {
isRunning[miniind] = false ;
isRunning[ele] = true ;
cost += 1;
}
else {
int farpos = find(arr, i, m, isRunning);
isRunning[arr[farpos]] = false ;
isRunning[ele] = true ;
cost += 1;
}
}
}
}
return cost;
}
int main()
{
int n1 = 3;
int m1 = 6;
vector< int > arr1{ 1, 2, 1, 3, 4, 1 };
cout << mincost(n1, m1, arr1) << endl;
int n2 = 2;
int m2 = 6;
vector< int > arr2{ 1, 2, 1, 3, 2, 1 };
cout << mincost(n2, m2, arr2) << endl;
int n3 = 3;
int m3 = 31;
vector< int > arr3{ 7, 11, 17, 10, 7, 10, 2, 9,
2, 18, 8, 10, 20, 10, 3, 20,
17, 17, 17, 1, 15, 10, 8, 3,
3, 18, 13, 2, 10, 10, 11 };
cout << mincost(n3, m3, arr3) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int find( int [] arr, int pos, int m,
boolean [] isRunning)
{
int [] d = new int [m + 1 ];
for ( int i = m - 1 ; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
int maxipos = 0 ;
for ( int ele : d)
maxipos = Math.max(ele, maxipos);
return maxipos;
}
static int mincost( int n, int m, int [] arr)
{
@SuppressWarnings ( "unchecked" )
Vector<Integer>[] freqarr = new Vector[m];
for ( int i = 0 ; i < freqarr.length; i++)
freqarr[i] = new Vector<Integer>();
int [] newvec = new int [m + 1 ];
for ( int i = 0 ; i < m + 1 ; i++)
freqarr[m - 1 ].add(newvec[i]);
for ( int i = m - 2 ; i > 0 ; i--)
{
Vector<Integer> nv = new Vector<>();
nv = freqarr[i + 1 ];
nv.insertElementAt(arr[i + 1 ] + 1 ,
arr[i + 1 ]);
freqarr[i] = nv;
}
boolean [] isRunning = new boolean [m + 1 ];
int cost = 0 ;
int truecount = 0 ;
for ( int i = 0 ; i < m; i++)
{
int ele = arr[i];
if (isRunning[ele] == true )
continue ;
else
{
if (truecount < n)
{
cost += 1 ;
truecount += 1 ;
isRunning[ele] = true ;
}
else
{
int mini = 100000 ;
int miniind = 0 ;
for ( int j = 0 ; j <= m; j++)
{
if (isRunning[j] && mini >
freqarr[i].get(j))
{
mini = freqarr[i].get(j);
miniind = j;
}
}
if (mini == 0 )
{
isRunning[miniind] = false ;
isRunning[ele] = true ;
cost += 1 ;
}
else
{
int farpos = find(arr, i, m,
isRunning);
isRunning[arr[farpos]] = false ;
isRunning[ele] = true ;
cost += 1 ;
}
}
}
}
return cost;
}
public static void main(String[] args)
{
int n1 = 3 ;
int m1 = 6 ;
int [] arr1 = { 1 , 2 , 1 , 3 , 4 , 1 };
System.out.print(mincost(n1, m1, arr1) + "\n" );
int n2 = 2 ;
int m2 = 6 ;
int [] arr2 = { 1 , 2 , 1 , 3 , 2 , 1 };
System.out.print(mincost(n2, m2, arr2) + "\n" );
int n3 = 3 ;
int m3 = 31 ;
int [] arr3 = { 7 , 11 , 17 , 10 , 7 , 10 ,
2 , 9 , 2 , 18 , 8 , 10 ,
20 , 10 , 3 , 20 , 17 , 17 ,
17 , 1 , 15 , 10 , 8 , 3 ,
3 , 18 , 13 , 2 , 10 , 10 , 11 };
System.out.print(mincost(n3, m3 - 8 , arr3) + "\n" );
}
}
|
Python3
def find(arr, pos, m, isRunning):
d = [ 0 ] * (m + 1 )
for i in range (m - 1 , pos, - 1 ):
if isRunning[arr[i]]:
d[arr[i]] = i
maxipos = 0
for ele in d:
maxipos = max (ele, maxipos)
return maxipos
def mincost(n, m, arr):
freqarr = [[] for i in range (m)]
newvec = [ 0 ] * (m + 1 )
freqarr[m - 1 ] = newvec[:]
for i in range (m - 2 , - 1 , - 1 ):
nv = freqarr[i + 1 ][:]
nv[arr[i + 1 ]] + = 1
freqarr[i] = nv[:]
isRunning = [ False ] * (m + 1 )
cost = 0
truecount = 0
for i in range ( 0 , m):
ele = arr[i]
if isRunning[ele] = = True :
continue
else :
if truecount < n:
cost + = 1
truecount + = 1
isRunning[ele] = True
else :
mini = 100000
miniind = 0
for j in range ( 1 , m + 1 ):
if isRunning[j] and mini > freqarr[i][j]:
mini = freqarr[i][j]
miniind = j
if mini = = 0 :
isRunning[miniind] = False
isRunning[ele] = True
cost + = 1
else :
farpos = find(arr, i, m, isRunning)
isRunning[arr[farpos]] = False
isRunning[ele] = True
cost + = 1
return cost
if __name__ = = "__main__" :
n1, m1 = 3 , 6
arr1 = [ 1 , 2 , 1 , 3 , 4 , 1 ]
print (mincost(n1, m1, arr1))
n2, m2 = 2 , 6
arr2 = [ 1 , 2 , 1 , 3 , 2 , 1 ]
print (mincost(n2, m2, arr2))
n3, m3 = 3 , 31
arr3 = [ 7 , 11 , 17 , 10 , 7 , 10 , 2 , 9 ,
2 , 18 , 8 , 10 , 20 , 10 , 3 , 20 ,
17 , 17 , 17 , 1 , 15 , 10 , 8 , 3 ,
3 , 18 , 13 , 2 , 10 , 10 , 11 ]
print (mincost(n3, m3, arr3))
|
C#
using System;
using System.Collections.Generic;
public class GFG{
static int find( int [] arr, int pos, int m,
bool [] isRunning)
{
int [] d = new int [m + 1];
for ( int i = m - 1; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
int maxipos = 0;
foreach ( int ele in d)
maxipos = Math.Max(ele, maxipos);
return maxipos;
}
static int mincost( int n, int m, int [] arr)
{
List< int >[] freqarr = new List< int >[m];
for ( int i = 0; i < freqarr.Length; i++)
freqarr[i] = new List< int >();
int [] newvec = new int [m + 1];
for ( int i = 0; i < m + 1; i++)
freqarr[m - 1].Add(newvec[i]);
for ( int i = m - 2; i > 0; i--)
{
List< int > nv = new List< int >();
nv = freqarr[i + 1];
nv[arr[i + 1]] += 1;
freqarr[i] = nv;
}
bool [] isRunning = new bool [m + 1];
int cost = 0;
int truecount = 0;
for ( int i = 0; i < m; i++)
{
int ele = arr[i];
if (isRunning[ele] == true )
continue ;
else
{
if (truecount < n)
{
cost += 1;
truecount += 1;
isRunning[ele] = true ;
}
else
{
int mini = 100000;
int miniind = 0;
for ( int j = 0; j <= m; j++)
{
if (isRunning[j] && mini >
freqarr[i][j])
{
mini = freqarr[i][j];
miniind = j;
}
}
if (mini == 0)
{
isRunning[miniind] = false ;
isRunning[ele] = true ;
cost += 1;
}
else
{
int farpos = find(arr, i, m,
isRunning);
isRunning[arr[farpos]] = false ;
isRunning[ele] = true ;
cost += 1;
}
}
}
}
return cost;
}
public static void Main(String[] args)
{
int n1 = 3;
int m1 = 6;
int [] arr1 = { 1, 2, 1, 3, 4, 1 };
Console.Write(mincost(n1, m1, arr1) + "\n" );
int n2 = 2;
int m2 = 6;
int [] arr2 = { 1, 2, 1, 3, 2, 1 };
Console.Write(mincost(n2, m2, arr2) + "\n" );
int n3 = 3;
int m3 = 31;
int [] arr3 = { 7, 11, 17, 10, 7, 10,
2, 9, 2, 18, 8, 10,
20, 10, 3, 20, 17, 17,
17, 1, 15, 10, 8, 3,
3, 18, 13, 2, 10, 10, 11 };
Console.Write(mincost(n3, m3 - 8, arr3) + "\n" );
}
}
|
Javascript
<script>
function find(arr, pos, m, isRunning)
{
let d = new Array(m + 1);
for (let i = m - 1; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
let maxipos = 0;
for (let ele in d)
maxipos = Math.max(ele, maxipos);
return maxipos;
}
function mincost(n, m, arr)
{
let freqarr = new Array(m);
for (let i = 0; i < freqarr.length; i++)
freqarr[i] = new Array();
let newvec = new Array(m+1);
for (let i = 0; i < m + 1; i++)
freqarr[m - 1].push(newvec[i]);
for (let i = m - 2; i > 0; i--)
{
let nv = new Array();
nv = freqarr[i + 1];
nv[arr[i + 1]] += 1;
freqarr[i] = nv;
}
let isRunning = new Array(m+1);
let cost = 0;
let truecount = 0;
for (let i = 0; i < m; i++)
{
let ele = arr[i];
if (isRunning[ele] == true )
continue ;
else
{
if (truecount < n)
{
cost += 1;
truecount += 1;
isRunning[ele] = true ;
}
else
{
let mini = 100000;
let miniind = 0;
for (let j = 0; j <= m; j++)
{
if (isRunning[j] && mini >
freqarr[i][j])
{
mini = freqarr[i][j];
miniind = j;
}
}
if (mini == 0)
{
isRunning[miniind] = false ;
isRunning[ele] = true ;
cost += 1;
}
else
{
let farpos = find(arr, i, m,
isRunning);
isRunning[arr[farpos]] = false ;
isRunning[ele] = true ;
cost += 1;
}
}
}
}
return cost;
}
let n1 = 3;
let m1 = 6;
let arr1 = [ 1, 2, 1, 3, 4, 1 ];
document.write(mincost(n1, m1, arr1) + "<br>" );
let n2 = 2;
let m2 = 6;
let arr2 = [ 1, 2, 1, 3, 2, 1 ];
document.write(mincost(n2, m2, arr2) + "<br>" );
let n3 = 3;
let m3 = 31;
let arr3 = [ 7, 11, 17, 10, 7, 10,
2, 9, 2, 18, 8, 10,
20, 10, 3, 20, 17, 17,
17, 1, 15, 10, 8, 3,
3, 18, 13, 2, 10, 10 , 11];
document.write(mincost(n3, m3+8, arr3) + 1 + "<br>" );
</script>
|
Complexity Analysis:
- Time Complexity: O(m^2) .
- Space Complexity: O(m^2), (to store the freqarr).