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; }