p-7-17最佳调度问题

1. 题目描述

假设有n(n<=20)个任务由k(k<=20)个可并行工作的机器完成。完成任务i需要的时间为ti。
试设计一个算法,对任意给定的整数n和k,以及完成任务i 需要的时间为ti
,i=1~n。计算完成这n个任务的最佳调度,使得完成全部任务的时间最早。

2. 输入格式:

输入数据的第一行有2 个正整数n和k。第2 行的n个正整数是完成n个任务需要的时间。 输出格式:

将计算出的完成全部任务的最早时间输出到屏幕。

3. 输入样例:
在这里给出一组输入。例如:
7 3
2 14 4 16 6 5 3
4. 输出样例:
在这里给出相应的输出。例如:

17
5. 解题思路

将k个时间看成k个容器,n个时间往里边放。给各个容器分配时间,在这个过程中会有m套方案,求出某套方案中三个容器中时间最多的,即完成全部任务的最早时间

脑海中要有n叉树

#include <bits/stdc++.h>
using namespace std;

int n, k;
int a[1001]; // 存放时间 
int x[1001]; // 存放分给每台机器的时间 
int res = 999999; //最优时间 

void dfs(int j, int s){ //j时间数组下标#
	if(j > n) // 说明到了叶子节点 
		if(s < res)
			res = s; // 找到当前最优解 更新 
	if(s >= res)
		return;
	for(int i = 0; i < k; i++){
		if(x[i] + a[j] < res){ // res可以动态变化  目的是求全过程的最优时间 
			x[i] += a[j];
			/*下一句是灵魂 
			1. 目的是求三台机器中用时最多的 
			2. 同一台机器时,x[i]自然比s大
			3. 不同台机器时,x[i]不一定比s大 
			*/ 
			dfs(j + 1, max(s, x[i]));
			x[i] -= a[j];
		}
	} 
}

int main(){
	cin >> n >> k;
	for(int i = 0; i < n; i++)
		cin >> a[i];
	dfs(0, 0);
	cout << res;
	return 0;
} 
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最佳调度问题指的是在一组任务中,如何安排任务的执行顺序,才能使任务的总执行时间最短。这个问题可以使用回溯算法进行求解。 回溯算法是一种基于深度优先搜索的算法。对于最佳调度问题,回溯算法的思路是:从第一个任务开始,依次枚举所有可能的下一个任务,计算当前任务序列的总执行时间,如果当前总执行时间已经大于已知的最小总执行时间,则剪枝,回溯到上一级任务,继续枚举其它可能的下一个任务;如果已经枚举完所有可能的下一个任务,则将当前任务序列作为最佳序列,并更新已知的最小总执行时间。然后回溯到上一级任务,继续枚举其它可能的下一个任务。 以下是最佳调度问题回溯法的C语言实现: ```c #include <stdio.h> #define MAXN 100 int n; // 任务数 int p[MAXN]; // 任务的执行时间 int order[MAXN]; // 当前的任务序列 int bestOrder[MAXN]; // 最佳任务序列 int minTime = 0x7fffffff; // 最小总执行时间 void dfs(int curTime, int curPos) { if (curPos == n) { // 已经排好了n个任务 if (curTime < minTime) { minTime = curTime; for (int i = 0; i < n; i++) { bestOrder[i] = order[i]; } } return; } for (int i = curPos; i < n; i++) { // 枚举下一个任务 int tmp = p[order[i]]; for (int j = i; j > curPos; j--) { order[j] = order[j - 1]; } order[curPos] = i; dfs(curTime + tmp * (n - curPos), curPos + 1); for (int j = curPos; j < i; j++) { order[j] = order[j + 1]; } order[i] = i; } } int main() { printf("请输入任务数n:"); scanf("%d", &n); printf("请输入%d个任务的执行时间:", n); for (int i = 0; i < n; i++) { scanf("%d", &p[i]); order[i] = bestOrder[i] = i; } dfs(0, 0); printf("最佳任务序列为:"); for (int i = 0; i < n; i++) { printf("%d ", bestOrder[i] + 1); } printf("\n总执行时间为:%d\n", minTime); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值