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

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

题目:

思路:
仅有一个任务时,所用的最短时间一定是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的总用时不变。
所需的完成时间为\(t_1 = max(dp[i-1][0]+a[i], dp[i-1][1])\)
同理,如果第i个任务在B上处理,
所需的完成时间为\(t_2 = max(dp[i-1][0], dp[i-1][1]+b[i])\)
比较两个任务的完成时间。如果\(t_1<t_2\),第i个任务在A上处理,能令总用时最小,即
\(dp[i][0] = dp[i-1][0]+a[i]\)
\(dp[i][1] = dp[i-1][1]\)
否则
\(dp[i][0] = dp[i-1][0]\)
\(dp[i][1] = dp[i-1][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 @ 2022-04-10 10:43  圣暖气片  阅读(403)  评论(1编辑  收藏  举报