有n个处理器内核。每个内核可以一次处理一个任务。不同的内核可以同时处理不同的任务,而不会影响其他任务。假设队列中有m个任务,并且处理器必须处理这m个任务。同样,这m个任务并非都是相似的类型。任务的类型用数字表示。因此,将m个任务表示为m个连续的数字,相同的数字表示相同类型的任务,例如1表示类型1的任务,2表示类型2的任务,依此类推。
最初,所有内核都是免费的。在内核中启动某种类型的任务需要花费一个成本,而该任务目前尚未在该内核中运行。在每个内核上开始启动任务时,将收取一个单位成本。例如,一个核心正在运行类型3任务,如果我们在该核心中再次分配类型3任务,则此分配的成本将为零。但是,如果我们分配类型2任务,则此分配的成本将是一个单位。核心将继续处理任务,直到将下一个任务分配给该核心为止。
例子 :
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
Explanation :
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
说明(对于第一个示例I / O):在这里,核心总数为3。让,A,B和C。首先在任何一个核心中分配类型1的任务->成本1单位。状态:A – 1,B –无,C –无。在其余2个内核中的任何一个中分配类型2的任务->成本1个单位。状态:A – 1,B – 2,C –无。然后在正在进行类型1任务的核心中分配类型1的任务->成本0单位。状态:A – 1,B – 2,C –无。
在自由核心->成本1单位中分配类型3的任务。状态:A – 1,B – 2,C – 3。
现在,所有核心都在运行任务。因此,我们必须在这些核心之一中分配类型4的任务。让我们将其加载到核心B中,先前的类型2任务正在进行->成本1单位。
状态:A – 1,B – 4,C –3。现在,将类型1任务加载到正在运行类型1任务的核心A中->成本0单位。状态:A – 1,B – 4,C –3。因此,总成本= 1 + 1 + 0 + 1 + 1 + 0 = 4 u
单位。
解释2(对于第二个示例I / O):内核总数为2。让A和B。任何一个内核中类型1的第一个处理任务->花费1个单位。州:A – 1,B –无。在其余2个内核中的任何一个中处理类型2的任务->花费1个单位。状态:A – 1,B –2。然后在正在进行类型1任务的核心中处理类型1的任务->成本0单位。状态:A – 1,B –2。现在,让我们将类型3的任务分配给核心A->成本1单位。状态:A – 3,B –2。现在,在核心B中分配类型2任务,其中类型2任务已经在进行->成本0单位。状态:A – 3,B –2。因此,总成本= 1 +1 + 0 +1 + 1 = 4个单位。最后在任何一个核心中分配类型1任务(例如A)->成本1单位。状态:A – 1,B –2。因此,总成本= 1 +1 + 0 +1 + 0 +1 = 4个单位。
方法:将此问题分为两种情况:
第一个是其中一个核心当前正在运行相同类型的任务。然后,只需将即将执行的任务分配给该核心即可。例如,在i = 3(第三个任务)时,当类型1任务出现时,我们可以将该任务分配给先前执行类型1任务的那个核心。此成本为0个单位。
第二种情况是在任何内核中都没有运行相同类型的任务。然后,可能有两种可能性。子情况1是,如果至少有一个空闲核心,则将即将到来的任务分配给该核心。
子情况2是,如果没有可用的核心,那么我们必须停止处理一种类型的任务,释放一个核心,并在该核心中分配即将到来的任务,以使将来的成本降至最低。为了最大程度地降低成本,我们应该停止一种以后不会再发生的任务。如果每个正在进行的任务将来至少发生一次,那么我们应该停止该任务,该任务将在所有当前正在进行的任务中最后一次发生(这是一种贪婪的方法,并且会执行任务)。
例如2:在i = 4(第四任务),类型3任务,当前正在进行的类型1和类型2任务位于两个内核中时,我们可以停止任务类型1或任务类型2以启动任务类型3。但是我们将停止任务类型1作为类型1任务在类型2任务之后发生。
C++
// C++ Program to fid out minimum
// cost to process m tasks
#include
using namespace std;
// Function to find out the farthest
// position where one of the currently
// ongoing tasks will rehappen.
int find(vector arr, int pos,
int m, vector isRunning)
{
// Iterate form last to current
// position and find where the
// task will happen next.
vector d(m + 1, 0);
for (int i = m; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
// Find out maximum of all these
// positions and it is the
// farthest position.
int maxipos = 0;
for (int ele : d)
maxipos = max(ele, maxipos);
return maxipos;
}
// Function to find out minimum cost to
// process all the tasks
int mincost(int n, int m, vector arr)
{
// freqarr[i][j] denotes the frequency
// of type j task after position i
// like in array {1, 2, 1, 3, 2, 1}
// frequency of type 1 task after
// position 0 is 2. So, for this
// array freqarr[0][1] = 2. Here,
// i can range in between 0 to m-1 and
// j can range in between 0 to m(though
// there is not any type 0 task).
vector > freqarr(m);
// Fill up the freqarr vector from
// last to first. After m-1 th position
// frequency of all type of tasks will be
// 0. Then at m-2 th position only frequency
// of arr[m-1] type task will be increased
// by 1. Again, in m-3 th position only
// frequency of type arr[m-2] task will
// be increased by 1 and so on.
vector newvec(m + 1, 0);
freqarr[m - 1] = newvec;
for (int i = m - 2; i >= 0; i--)
{
vector nv;
nv = freqarr[i + 1];
nv[arr[i + 1]] += 1;
freqarr[i] = nv;
}
// isRunning[i] denotes whether type i
// task is currently running in one
// of the cores.
// At the beginning no tasks are
// running so all values are false.
vector isRunning(m + 1, false);
// cost denotes total cost to assign tasks
int cost = 0;
// truecount denotes number of occupied cores
int truecount = 0;
// iterate through each task and find the
// total cost.
for (int i = 0; i < m; i++) {
// ele denotes type of task.
int ele = arr[i];
// Case 1: if smae type of task is
// currently running cost for this
// is 0.
if (isRunning[ele] == true)
continue;
// Case 2: same type of task is not
// currently running.
else {
// Subcase 1: if there is at least
// one free core then assign this task
// to that core at a cost of 1 unit.
if (truecount < n) {
cost += 1;
truecount += 1;
isRunning[ele] = true;
}
// Subcase 2: No core is free
else {
// here we will first find the minimum
// frequency among all the ongoing tasks
// in future.
// If the minimum frequency is 0 then
// there is at least one ongoing task
// which will not occur again. Then we just
// stop tha task.
// If minimum frequency is >0 then, all the
// tasks will occur at least once in future.
// we have to find out which of these will
// rehappen last among the all ongoing tasks.
// set minimum frequency to a big number
int mini = 100000;
// set index of minimum frequency task to 0.
int miniind = 0;
// find the minimum frequency task type(miniind)
// and frequency(mini).
for (int j = 1; j <= m; j++) {
if (isRunning[j] && mini > freqarr[i][j]) {
mini = freqarr[i][j];
miniind = j;
}
}
// If minimum frequency is zero then just stop
// the task and start the present task in that
// core. Cost for this is 1 unit.
if (mini == 0) {
isRunning[miniind] = false;
isRunning[ele] = true;
cost += 1;
}
// If minimum frequency is nonzero then find
// the farthest position where one of the
// ongoing task will rehappen.
// Stop that task and start present task
// in that core.
else {
// find out the farthest position using
// find function
int farpos = find(arr, i, m, isRunning);
isRunning[arr[farpos]] = false;
isRunning[ele] = true;
cost += 1;
}
}
}
}
// return total cost
return cost;
}
// Driver Program
int main()
{
// Test case 1
int n1 = 3;
int m1 = 6;
vector arr1{ 1, 2, 1, 3, 4, 1 };
cout << mincost(n1, m1, arr1) << endl;
// Test case 2
int n2 = 2;
int m2 = 6;
vector arr2{ 1, 2, 1, 3, 2, 1 };
cout << mincost(n2, m2, arr2) << endl;
// Test case 3
int n3 = 3;
int m3 = 31;
vector 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
// Java program to fid out minimum
// cost to process m tasks
import java.util.*;
class GFG{
// Function to find out the farthest
// position where one of the currently
// ongoing tasks will rehappen.
static int find(int[] arr, int pos, int m,
boolean[] isRunning)
{
// Iterate form last to current
// position and find where the
// task will happen next.
int[] d = new int[m + 1];
for(int i = m - 1; i > pos; i--)
{
if (isRunning[arr[i]])
d[arr[i]] = i;
}
// Find out maximum of all these
// positions and it is the
// farthest position.
int maxipos = 0;
for(int ele : d)
maxipos = Math.max(ele, maxipos);
return maxipos;
}
// Function to find out minimum cost to
// process all the tasks
static int mincost(int n, int m, int[] arr)
{
// freqarr[i][j] denotes the frequency
// of type j task after position i
// like in array {1, 2, 1, 3, 2, 1}
// frequency of type 1 task after
// position 0 is 2. So, for this
// array freqarr[0][1] = 2. Here,
// i can range in between 0 to m-1 and
// j can range in between 0 to m(though
// there is not any type 0 task).
@SuppressWarnings("unchecked")
Vector[] freqarr = new Vector[m];
for(int i = 0; i < freqarr.length; i++)
freqarr[i] = new Vector();
// Fill up the freqarr vector from
// last to first. After m-1 th position
// frequency of all type of tasks will be
// 0. Then at m-2 th position only frequency
// of arr[m-1] type task will be increased
// by 1. Again, in m-3 th position only
// frequency of type arr[m-2] task will
// be increased by 1 and so on.
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 nv = new Vector<>();
nv = freqarr[i + 1];
nv.insertElementAt(arr[i + 1] + 1,
arr[i + 1]);
freqarr[i] = nv;
}
// isRunning[i] denotes whether type i
// task is currently running in one
// of the cores.
// At the beginning no tasks are
// running so all values are false.
boolean[] isRunning = new boolean[m + 1];
// cost denotes total cost to assign tasks
int cost = 0;
// truecount denotes number of occupied cores
int truecount = 0;
// Iterate through each task and find the
// total cost.
for(int i = 0; i < m; i++)
{
// ele denotes type of task.
int ele = arr[i];
// Case 1: if smae type of task is
// currently running cost for this
// is 0.
if (isRunning[ele] == true)
continue;
// Case 2: same type of task is not
// currently running.
else
{
// Subcase 1: if there is at least
// one free core then assign this task
// to that core at a cost of 1 unit.
if (truecount < n)
{
cost += 1;
truecount += 1;
isRunning[ele] = true;
}
// Subcase 2: No core is free
else
{
// Here we will first find the minimum
// frequency among all the ongoing tasks
// in future.
// If the minimum frequency is 0 then
// there is at least one ongoing task
// which will not occur again. Then we just
// stop tha task.
// If minimum frequency is >0 then, all the
// tasks will occur at least once in future.
// we have to find out which of these will
// rehappen last among the all ongoing tasks.
// Set minimum frequency to a big number
int mini = 100000;
// Set index of minimum frequency task to 0.
int miniind = 0;
// Find the minimum frequency task
// type(miniind) and frequency(mini).
for(int j = 0; j <= m; j++)
{
if (isRunning[j] && mini >
freqarr[i].get(j))
{
mini = freqarr[i].get(j);
miniind = j;
}
}
// If minimum frequency is zero then
// just stop the task and start the
// present task in that core. Cost
// for this is 1 unit.
if (mini == 0)
{
isRunning[miniind] = false;
isRunning[ele] = true;
cost += 1;
}
// If minimum frequency is nonzero
// then find the farthest position
// where one of the ongoing task
// will rehappen.Stop that task
// and start present task in that
// core.
else
{
// Find out the farthest position
// using find function
int farpos = find(arr, i, m,
isRunning);
isRunning[arr[farpos]] = false;
isRunning[ele] = true;
cost += 1;
}
}
}
}
// Return total cost
return cost;
}
// Driver code
public static void main(String[] args)
{
// Test case 1
int n1 = 3;
int m1 = 6;
int[] arr1 = { 1, 2, 1, 3, 4, 1 };
System.out.print(mincost(n1, m1, arr1) + "\n");
// Test case 2
int n2 = 2;
int m2 = 6;
int[] arr2 = { 1, 2, 1, 3, 2, 1 };
System.out.print(mincost(n2, m2, arr2) + "\n");
// Test case 3
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");
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 Program to fid out
# minimum cost to process m tasks
# Function to find out the farthest
# position where one of the currently
# ongoing tasks will rehappen.
def find(arr, pos, m, isRunning):
# Iterate form last to current
# position and find where the
# task will happen next.
d = [0] * (m + 1)
for i in range(m - 1, pos, -1):
if isRunning[arr[i]]:
d[arr[i]] = i
# Find out maximum of all these positions
# and it is the farthest position.
maxipos = 0
for ele in d:
maxipos = max(ele, maxipos)
return maxipos
# Function to find out minimum
# cost to process all the tasks
def mincost(n, m, arr):
# freqarr[i][j] denotes the frequency
# of type j task after position i
# like in array 1, 2, 1, 3, 2, 1
# frequency of type 1 task after
# position 0 is 2. So, for this
# array freqarr[0][1] = 2. Here,
# i can range in between 0 to m-1 and
# j can range in between 0 to m(though
# there is not any type 0 task).
freqarr = [[] for i in range(m)]
# Fill up the freqarr vector from
# last to first. After m-1 th position
# frequency of all type of tasks will be
# 0. Then at m-2 th position only frequency
# of arr[m-1] type task will be increased
# by 1. Again, in m-3 th position only
# frequency of type arr[m-2] task will
# be increased by 1 and so on.
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[i] denotes whether type i
# task is currently running in one
# of the cores.
# At the beginning no tasks are
# running so all values are false.
isRunning = [False] * (m + 1)
# cost denotes total cost to assign tasks
cost = 0
# truecount denotes number of occupied cores
truecount = 0
# iterate through each task
# and find the total cost.
for i in range(0, m):
# ele denotes type of task.
ele = arr[i]
# Case 1: if smae type of task is
# currently running cost for this is 0.
if isRunning[ele] == True:
continue
# Case 2: same type of task
# is not currently running.
else:
# Subcase 1: if there is at least
# one free core then assign this task
# to that core at a cost of 1 unit.
if truecount < n:
cost += 1
truecount += 1
isRunning[ele] = True
# Subcase 2: No core is free
else:
# here we will first find the minimum
# frequency among all the ongoing tasks
# in future.
# If the minimum frequency is 0 then
# there is at least one ongoing task
# which will not occur again. Then we just
# stop tha task.
# If minimum frequency is >0 then, all the
# tasks will occur at least once in future.
# we have to find out which of these will
# rehappen last among the all ongoing tasks.
# set minimum frequency to a big number
mini = 100000
# set index of minimum frequency task to 0.
miniind = 0
# find the minimum frequency task
# type(miniind) and frequency(mini).
for j in range(1, m + 1):
if isRunning[j] and mini > freqarr[i][j]:
mini = freqarr[i][j]
miniind = j
# If minimum frequency is zero then just stop
# the task and start the present task in that
# core. Cost for this is 1 unit.
if mini == 0:
isRunning[miniind] = False
isRunning[ele] = True
cost += 1
# If minimum frequency is nonzero then find
# the farthest position where one of the
# ongoing task will rehappen.
# Stop that task and start present task
# in that core.
else:
# find out the farthest position
# using find function
farpos = find(arr, i, m, isRunning)
isRunning[arr[farpos]] = False
isRunning[ele] = True
cost += 1
# return total cost
return cost
# Driver Code
if __name__ == "__main__":
# Test case 1
n1, m1 = 3, 6
arr1 = [1, 2, 1, 3, 4, 1]
print(mincost(n1, m1, arr1))
# Test case 2
n2, m2 = 2, 6
arr2 = [1, 2, 1, 3, 2, 1]
print(mincost(n2, m2, arr2))
# Test case 3
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))
# This code is contributed by Rituraj Jain
4
4
18
时间复杂度: O(m ^ 2)
空间复杂度: O(m ^ 2),(存储频率)