代码改变世界

第五章实践

2018-12-24 23:20  灿灿林  阅读(145)  评论(0)    收藏  举报

1、实践题目:工作分配问题

2、问题描述

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

输入格式:

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

输出格式:

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

输入样例:

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

3

10 2 3

2 3 4

3 4 5

输出样例:

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

9

3、算法描述(包括解空间,画出测试样例的解空间树,剪枝(约束函数或限界函数)方法描述)

n件工作,故解空间为n

解空间树如下:

 

 

 

剪枝方法:若当前工人的费用加上之前的总费用大于目前求得的最少费用则不继续执行。

a[dep][r]表示第dep个人做第r个工作的费用

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int a[100][100],sum,minn,i,j,n;

bool b[100];

 

void dfs(int dep){

int r;

for (r=1;r<=n;++r)

if (!b[r]){

   b[r]=1;

   sum+=a[dep][r];

   if (dep==n){

   if(sum<minn)

      minn=sum;

   }

   else

     if(sum<minn)   

dfs(dep+1);

   sum-=a[dep][r];

   b[r]=0;

}

}

 

int main()

{

scanf("%d",&n);

for (i=1;i<=n;++i)

for (j=1;j<=n;++j)

    scanf("%d",&a[i][j]);

sum=0;

minn=10000000;

dfs(1);

printf("%d",minn);

return 0;

}

 

4心得体会(对本次实践收获及疑惑进行总结)

回溯法的精髓在于剪枝,那就需要约束函数或限界函数去实现。结对编程讨论这些限界条件会有比较大的争议,大家按照自己方法做出来再讨论比较有效率。难点在于解空间的确定。我和队友最后达成一致。