1420: 深入浅出学算法103-工作分配问题

题目描述

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

设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小

输入

由文件job.in给出输入数据。第一行有1个正整数n (1≤n≤20)。接下来的n行,每行n个数,第i行表示第i个人各项工作费用。

输出

将计算出的最小总费用输出到文件job.out。

样例输入 Copy

3
4  2  5
2  3  6
3  4  5

样例输出 Copy

9

先放上我时间超限(80%)的代码:(纯dfs搜索)

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 25
using namespace std;
int c[N][N];
bool st[N];
int res=1e9;
int sum=0;
int n;
void dfs(int u)//遍历人,看看每个人挑啥 
{
	if(u>n)
	{
		res=min(res,sum);
		return;
	}
	for(int i=1;i<=n;i++)
	{//每个人挑物品 
		if(st[i]!=true)//物品没有被挑过 
		{
			sum+=c[i][u];
			st[i]=true;
			dfs(u+1);
			st[i]=false;
			sum-=c[i][u];	
		}
	}
	return;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)//i件物品 
		for(int j=1;j<=n;j++)//j个人 
			cin>>c[i][j];
	memset(st,false,sizeof st);
	dfs(1);
	cout<<res<<endl;
	return 0;
}

剪枝之后的AC代码:(将还没搜索完但是金额已经超出最小方案的方案过滤掉)

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 25
#define long long int
using namespace std;
int c[N][N];
bool st[N];
int res=1e18;
int sum=0,cost=0;
int n;
void dfs(int u,int sum)//遍历人,看每个人挑啥 
{
	if(u>n && sum<cost)//只要小了就可以更新 
	{
		cost=sum;
		return;
	}
	if(cost>=sum)//过滤以及超出之前金额的方案 
	{
		for(int i=1;i<=n;i++)
		{//每个人挑物品
			if(st[i]!=true)
			{
				st[i]=true;
				dfs(u+1,sum+c[i][u]);
				st[i]=false;
			}	
		}
	}
	return;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)//i件物品 
	{
		for(int j=1;j<=n;j++)//j个人 
		{
			cin>>c[i][j];
		}
		cost+=c[i][i];//随机设置一个可行的方案作为对照组 
	}	
	memset(st,false,sizeof st);//物品都没有被存过 
	dfs(1,0);//从第一个人开始搜索 
	cout<<cost<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值