算法第5章上机实践报告

一、实践题目

 

7-2 工作分配问题 (20 分)

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

输入格式:

输入数据的第一行有1 个正整数n (1≤n≤20)。接下来的n行,每行n个数,表示工作费用。

输出格式:

将计算出的最小总费用输出到屏幕。

输入样例:

在这里给出一组输入。例如:

3
10 2 3
2 3 4
3 4 5

输出样例:

在这里给出相应的输出。例如:

9

二、问题描述

  找到一个工作序列,使得总费用最小。实际上是一个排列树的问题。

三、算法描述

  构造一棵排列树,使得工作费用最小。

  假设n=3,其排列树为

其剪枝函数为:if (temp + a[t][x[i]]< best) 遍历该分支
其中temp表示当前费用,
a[t][x[i]]表示第t个人分配第x[i]个工作的费用,best表示已得到的最低费用
#include <iostream>
using namespace std;

int n;
int a[1000][1000];
int x[1000];
int temp=0;
int best=1e9;

void Backtrack(int t) {
    if(t>n){
        if (temp < best) {
            best = temp;
        }
        return ;
    }
    else {
        for (int i = t; i <= n; i++) {
            if (temp + a[t][x[i]]< best){
                temp +=a[t][x[i]];
                swap(x[t],x[i]);
                Backtrack(t+1);
                swap(x[t],x[i]);
                temp -=a[t][x[i]];
            }
        }
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
        x[i]=i;
    Backtrack(1);
    cout<<best;
    return 0;
}

四、心得体会

这道题类似于旅行售货员问题,但简单一点,因此借鉴了一下写出了这段代码。但中途和队友出现了一点分歧导致我们分道扬镳,我坚持采用当前的做法但队友起初有点难以理解旅行售货员算法的问题而弃用了,最后还是我成功说服了他。

 
 
posted @ 2018-12-21 21:15  underdestiny  阅读(147)  评论(0编辑  收藏  举报