工作分配问题(dfs)

题目

背景描述

设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为Cij。试设计一个算法,为每一个人都分配一件不同的工作,并使总费用达到最小。 
设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。

输入

第一行有1个正整数n (1≤n≤20)。接下来的n行,每行n个数,第i行表示第i个人各项工作费用。

输出

计算出的最小总费用

样例输入

3
4 2 5
2 3 6
3 4 5

样例输出

9

非优化部分

分析

最基本的思路就是遍历所有的情况,计算出最小的花费。思路可以类似N皇后问题,设一个一维数组记录第i个岗位由第j个人来完成,然后计算出该方案所需的费用,与最当前的最小值比较。但是这种算法和for循环遍历情况是一样的,时间复杂度为O(2^n)。

代码

#include 
using namespace std;
typedef long long ll;

ll n,minn=INT_MAX;
ll a[25][25];
ll ans[25];
ll sum=0;

bool judge(int t)//判断填入的工作是不是满足要求;
{
	for(int i=0;i>n;
	for(int i=0;i>a[i][j]; 
		}
	}
	dfs(0);
	cout<

这一代码很显然跑的时间是很长的,很容易超时;

优化部分

优化分析

引用子集和问题的思路,同样我们设一个数组,来标记该工作是否已经有人去完成。深搜时间我们加入一个变量来求和,同时在我们的dfs函数中加入一个判断条件,如果当前的费用和已经超过当前确定的最小值,则停止深搜来剪枝,减少不必要的过程,节省时间。

优化代码

#include 
using namespace std;
typedef long long ll;

ll n,minn=INT_MAX;//定义全局变量n,和一个值非常大的minn来表示当前的最小值; 
ll a[25][25];//定义一个二位数组表示每一位的工人完成每一项工作所需要的费用; 
ll flag[25];//标记工作是否有人来做; 

void dfs(int t,int sum)//深搜函数,t表示工人的编号,sum计算该方案所需要花费的费用; 
{
	if(sum>=minn)//如果当前费用已经大于当前的最小值,则剪去这一枝; 
		return;
	if(t==n)//深搜结束条件 
	{
		if(minn>sum)//如果当前的最小值大于该方案的费用,则替换minn的值
		//这一判断条件可以不用加,因为之前已经将大于minn的sum全部去除,这里就可以直接替换minn的值; 
		minn=sum;
	}
	for(int i=0;i

你可能感兴趣的:(训练赛,深度优先,算法,c++)