#84(支线第七站)【二分答案+深度优先搜索】最佳调度

Description

【问题描述】 
       假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。 
【编程任务】 
       对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1~n。编程计算完成这n个任务的最佳调度。

 

Input

由文件machine.in给出输入数据。第一行有2 个正整数n和k。第2 行的n个正整数是完成n个任务需要的时间。

Output

 将计算出的完成全部任务的最早时间输出到文件machine.out。 

Sample Input

7  3
2  14  4  16  6  5  3

Sample Output

17

这又是一道非常非常经典的深度优先搜索+二分的题目......

#include 
#include 
#include 

#define SIZE 102

using namespace std;

int a[SIZE], s[SIZE] = {0}, n, k;

bool cmp(int a, int b)
{
	return (a > b);
}

bool dfs(int x, int mid) // 深搜判定
{
	int i;
	
	if (x > n) // 全部做完,可以
	{
		return true;
	}
	
	for (i = 1; i <= k; i++)
	{
		if (a[x] > mid) // 大于限定时间,不成
		{
			return false;
		}
		
		s[i] += a[x];
		
		if (s[i] <= mid)
		{
			if (dfs(x + 1, mid)) // 只要有一个分支搜索成立
			{
				return true; // 那么这个搜索就成立
			}
		}
		s[i] -= a[x];
	}
	
	return false;
}

int main(int argc, char** argv)
{
	int i, sum = 0, l, r, res, mid;
	
	cin >> n >> k;
	for (i = 1; i <= n; i++)
	{
		cin >> a[i];
		sum += a[i];
	}
	
	sort(a + 1, a + n + 1, cmp);
	
	l = sum / k;
	r = sum;
	while (l <= r) // 哇哇哇,又是二分答案
	{
		mid = l + (r - l) / 2; // 防溢出专用
		memset(s, 0, sizeof(s));
		if (dfs(1, mid))
		{
			res = mid;
			r = mid - 1;
		}
		else
		{
			l = mid + 1;
		}
	}
	
	cout << res << endl;
	
	return 0;
}

 

你可能感兴趣的:(刷题,gdgzoi刷题)