【9503】工作分配问题

Time Limit: 10 second
Memory Limit: 2 MB

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

Input

第一行是1 个正整数n (1 ≤n ≤20),表示有n 件工作分配给n 个人,接下来的n 行,每行n 个数,表示工作费用 。

Output

输出有m行,每行输出最小总费用。

Sample Input

3
4 2 5
2 3 6
3 4 5

Sample Output

9
 

【题解】

以人为搜索对象一个人一个人地搜。用一个bool型的bo数组来表示某个工作是否有被占用。用sum来累加当前的花费。可以用sum和min的值的比较来剪枝,即sum > min就剪掉。

【代码】

#include <cstdio>

int n,c[21][21],min = 2100000000,sum = 0;
bool bo[21];

void input_data()
{
    scanf("%d",&n);
    for (int i = 1;i <= n;i++)
        for (int j = 1;j <= n;j++) //输入每个工作对每个人的工资
           scanf("%d",&c[i][j]);
    for (int i = 1;i <= n;i++) //一开始所有工作都可以选
        bo[i] = true;
}

void sear_ch(int x)
{
    if (sum > min) return; //如果sum大于最小值 就剪枝
    if (x == (n+1)) //如果所有人都分配完了 就更新解
        {
            if (sum < min)
                min = sum;
            return;
        }
    for (int i = 1;i <= n;i++) //为x分配工作
        if (bo[i])
            {
                sum+=c[i][x]; //累加花费
                bo[i] = false; //标记工作不能再选。
                sear_ch(x+1);
                sum-=c[i][x];
                bo[i] = true;
            }
}

void get_ans()
{
    sear_ch(1); //从第一个人开始分配
}

void output_ans()
{
    printf("%d",min);
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    input_data();
    get_ans();
    output_ans();
    return 0;
}


 

原文地址:https://www.cnblogs.com/AWCXV/p/7632441.html