算法作业 | 独立任务最优调度问题

看答案和看网上的题解都有点懵,只能自己写了……把这种虽然有点蠢但是(对我自己来说)稍微好懂一点的方法发出来存一下档。

题目:

思路:
仅有一个任务时,所用的最短时间一定是a[0]和b[0]中的最小值。

有两个及以上任务时,用dp数组来存放执行任务所用的时间;其中dp[i][j]表示第i个任务完成时,机器j(取0/1)的总用时。
对于开始的两个任务,需要考虑四种情况(“A执行任务0,B执行任务1”,“A执行任务1,B执行任务0”,“A执行任务0、1”,“B执行任务0、1”),通过比较得出最小的用时。
即,找到max(a[0],b[1]),max(b[0],a[1]),a[0]+a[1],b[0]+b[1]四种情况中的最小值,然后对应地填入dp数组中。
如输入为

2
2 5
3 8

时,用时最小的是max(a[1],b[0])=5,此时任务1由B执行,任务0由A执行,最小用时为5.
输入为

2
1 1
4 8

时,用时最小的是a[0]+a[1]=2,此时任务0,1由A顺序执行,最小用时为2.

对于接下来的任务,需要考虑将新的任务放到哪个机器中来执行能够得到最小用时。
如果第i个任务在A上处理,则此时A的总用时在"第i-1个任务完成时所用时间"的基础上增加,B的总用时不变。
所需的完成时间为t1=max(dp[i1][0]+a[i],dp[i1][1])
同理,如果第i个任务在B上处理,
所需的完成时间为t2=max(dp[i1][0],dp[i1][1]+b[i])
比较两个任务的完成时间。如果t1<t2,第i个任务在A上处理,能令总用时最小,即
dp[i][0]=dp[i1][0]+a[i]
dp[i][1]=dp[i1][1]
否则
dp[i][0]=dp[i1][0]
dp[i][1]=dp[i1][1]+b[i]

以此类推,最终求得的最短时间是AB机器在最后一个任务执行结束后各自用时的最大值。

实现功能的具体代码如下:

int solution(int n, int a[], int b[])
{
	if(n==0)
		return 0;
	if(n==1)
		return min(a[0], b[0]);
	
	vector<vector<int>> dp(n, vector<int>(2, 0));
	// dp[i][j]: 表示第i个任务完成时,机器j的总用时 

	int m;
	if(max(a[1], b[0]) < max(a[0], b[1])){
		dp[0][1] = b[0];
		dp[1][0] = a[1];
		m = max(a[1], b[0]);
	}
	else{
		dp[0][0] = a[0];
		dp[1][1] = b[1];
		m = max(a[0], b[1]);
	}
	
	if(m > a[0]+a[1]){
		m = a[0]+a[1];
		dp[0][0] = a[0];
		dp[0][1] = 0;
		dp[1][0] = a[0] + a[1];
		dp[1][1] = 0;
	}
	
	if(m > b[0]+b[1]){
		dp[0][0] = 0;
		dp[0][1] = b[0];
		dp[1][0] = 0;
		dp[1][1] = b[0] + b[1];
	}
	
	for(int i=2; i<n; i++){
		if(max(dp[i-1][0]+a[i], dp[i-1][1]) < max(dp[i-1][1]+b[i], dp[i-1][0])){
			dp[i][0] = dp[i-1][0]+a[i];
			dp[i][1] = dp[i-1][1];
		}
		else{
			dp[i][0] = dp[i-1][0];
			dp[i][1] = dp[i-1][1] + b[i];
		}
	}
	
	int res = max(dp[n-1][0], dp[n-1][1]);

	return res;
}
posted @   圣暖气片  阅读(450)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示