【计算机算法】工作分配问题

工作分配问题

问题描述:设有n件工作分配给n个人。将工作i分配给第j个人的费用为cij,请设计算法,为每个人都分配1件不同的工作,并使得总费用达到最小。

实现提示:该问题的解空间是一棵排列树,可用搜索排列树的回溯框架实现。

代码如下:

#include<iostream>
#include<climits>
using namespace std;

int work[100];// 工作数组,用于存储工作编号
int work_fee[100][100];// 每个工人对应的每个工作的费用
int n, minsum= INT_MAX, newsum=0;// n表示工人个数,minsum表示最小费用和,newsum表示最新费用和

void backTrack(int k) {
    
    
	int number; // 工作编号
	if (k > n) {
    
    // 到达叶子节点
		if (newsum < minsum) {
    
     // 当最新费用小于当前最小费用时,更新最小费用
			minsum = newsum;
		}
		return;
	}

	else {
    
    // 未到达叶子节点,继续
		for (int i = k; i <= n; i++) {
    
    
			number = work[i]; // 工作编号
			newsum = newsum + work_fee[k][number];// 将当前工人k的number号工作加入最新工作费用
			swap(work[k], work[i]);// 交换两个位置上的工作编号
			if (newsum < minsum) {
    
     //当最新费用小于当前最小费用,继续下一个数
				backTrack(k + 1);
			}
			swap(work[k], work[i]);// 还原之前交换的工作编号
			newsum = newsum - work_fee[k][number];// 减去之前加入的数
		}
	}
}

int main() {
    
    
	cin >> n; // 输入工人数
	for (int i = 1; i <=n; i++) {
    
     // 初始化工作费用
		for (int j = 1; j <= n; j++) {
    
    
			cin >> work_fee[i][j];
		}
	}
	for (int i = 1; i <= n; i++) {
    
    // 初始化工作编号
		work[i] = i;
	}
	backTrack(1);// 回溯查找
	cout << minsum << endl; // 输出最小费用
	return 0;
}

在这里插入图片描述

Guess you like

Origin blog.csdn.net/passer__jw767/article/details/111875690