leetcode 1882. 使用服务器处理任务【优先队列】

给你两个 下标从 0 开始 的整数数组 servers 和 tasks ,长度分别为 n​​​​​​ 和 m​​​​​​ 。servers[i] 是第 i​​​​​​​​​​ 台服务器的 权重 ,而 tasks[j] 是处理第 j​​​​​​ 项任务 所需要的时间(单位:秒)。
你正在运行一个仿真系统,在处理完所有任务后,该系统将会关闭。每台服务器只能同时处理一项任务。第 0 项任务在第 0 秒可以开始处理,相应地,第 j 项任务在第 j 秒可以开始处理。处理第 j 项任务时,你需要为它分配一台 权重最小 的空闲服务器。如果存在多台相同权重的空闲服务器,请选择 下标最小 的服务器。如果一台空闲服务器在第 t 秒分配到第 j 项任务,那么在 t + tasks[j] 时它将恢复空闲状态。
如果没有空闲服务器,则必须等待,直到出现一台空闲服务器,并 尽可能早 地处理剩余任务。 如果有多项任务等待分配,则按照 下标递增 的顺序完成分配。
如果同一时刻存在多台空闲服务器,可以同时将多项任务分别分配给它们。
构建长度为 m 的答案数组 ans ,其中 ans[j] 是第 j 项任务分配的服务器的下标。
返回答案数组 ans​​​​ 。
原题链接

解析:建立两个优先队列,分别维护已使用服务器和空闲服务器,根据题目写仿函数排序规则。
可以采用遍历任务或时间两种方式。遍历时间时,步长为1s时会TLE,应当为每次直达的time。其次注意,自开始起,每过1s就有一个任务能够接受服务,delayTask标记当前排队的任务数。

class Server
{
public:
	long long startTime;
	int cost;
	int index;
};

class FreeServer
{
public:
	bool operator()(Server s1, Server s2)
	{
		if (s1.cost != s2.cost)
			return s1.cost > s2.cost;
		return s1.index > s2.index;
	}
};

class UsedServer
{
public: 
	bool operator()(Server s1, Server s2)
	{
		return s1.startTime > s2.startTime;
	}
};

vector<int> assignTasks(vector<int>& servers, vector<int>& tasks)
{
	priority_queue<Server, vector<Server>, FreeServer> pqFree;
	priority_queue<Server, vector<Server>, UsedServer> pqUsed;
	vector<int> ans;

	int serverNum;
	int taskNum;
	Server stmp;

	serverNum = servers.size();
	for (int i = 0; i < serverNum; ++i)
	{
		stmp.cost = servers[i];
		stmp.index = i;
		stmp.startTime = 0;
		pqFree.push(stmp);
	}

	int op = 0, delayTask = 1;
	taskNum = tasks.size();
	long long time = 0;
	while (op != taskNum)
	{
		while (!pqUsed.empty())
		{
			stmp = pqUsed.top();
			if (stmp.startTime > time)
				break;

			pqUsed.pop();
			pqFree.push(stmp);
		}
		
		while (!pqFree.empty())
		{
			stmp = pqFree.top();
			pqFree.pop();

			stmp.startTime = time + tasks[op];
			pqUsed.push(stmp);
			ans.push_back(stmp.index);
			op++;
			delayTask--;
			if (op == taskNum || delayTask == 0)
				break;
		}

		if (pqFree.empty())
		{
			delayTask = (int)(delayTask + pqUsed.top().startTime - time);
			time = pqUsed.top().startTime;
		}
		else
		{
			delayTask++;
			time++;
		}

		delayTask = min(delayTask, taskNum - op);
	}

	return ans;
}

// 补充输入
int main()
{
	int n, m, tmp;
	vector<int> servers;
	vector<int> tasks;

	scanf_s("%d %d", &n, &m);
	for (int i = 0; i < n; ++i)
	{
		scanf_s("%d", &tmp);
		servers.push_back(tmp);
	}

	for (int i = 0; i < m; ++i)
	{
		scanf_s("%d", &tmp);
		tasks.push_back(tmp);
	}

	assignTasks(servers, tasks);

	return 0;
}

/*
3 6
3 3 2
1 2 3 2 1 2
ans:[2,2,0,2,1,2]

5 7
5 1 4 3 2
2 1 2 4 5 2 1
ans:[1,4,1,4,1,3,2]

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值