代码改变世界

第五章实践报告

2018-12-20 09:30  water_chen  阅读(145)  评论(0编辑  收藏  举报

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

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

3、算法描述

解空间:排列树(三叉树)

 

代码描述:

#include<iostream>
using namespace std;
int a[100][100],sum=0,minn=2147483647,i,j,n;
int b[100];
void dfs(int dep)
{
 
    int r;
    for (r=1;r<=n;++r)//dep表示第几个人,r表示工作
      if (!b[r])
      {
          b[r]=1;
          sum+=a[dep][r];//a[dep][r]表示第dep个人做第r个工作的费用
           if (dep==n&&sum<minn)
          {
                 minn=sum;
          }
          if(dep!=n)
           {
               if (sum<minn)//剪枝  如果在分配完工作之前,sum已经比minn大了,直接遍历右子树
                  dfs(dep+1);
         }
          sum-=a[dep][r];//回溯一步
          b[r]=0;
      }
}
int main()
{
    cin>>n;
    for (i=1;i<=n;++i)
      for (j=1;j<=n;++j)
        cin>>a[i][j];
    dfs(1);
    cout<<minn<<endl;
    return 0;
}

时间复杂度:假设工作是n,则是n的平方

空间复杂度:建立了辅助数组b来存放工作分配的情况,所以空间复杂度是O(n)

 通过创建b数组和minn来辅助剪枝。

4、感悟

主要是工作取不取以及该怎么剪枝的问题,对于工作要保证不重复选,这个是我们思考最久的。回溯法这方面还不能很好的掌握。