第五章实验报告

实践题目:

  工作分配问题

问题描述:

设有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后问题进化版。

  剪枝用了两种,一种是n后问题里面的不同行不同列(bound函数实现),一种是目前花销(money)与当前最优解(best)比较,(在调用bound之后就开始比了)

  至于解空间和解空间树,我在下列的代码中加了两个money的输出,得到的解空间有(10,3,5),(10,4,4),(2,2,5),(2,4,3),(3,2,5),(3,3,3)

解空间树如图

我的代码如下:

代码里面cost、t、i等等都是从1开始的!!

  

 1 #include <iostream>
 2 using namespace std;
 3 int best=10000;
 4 bool bound(int k,int x[]){
 5     for(int j=1;j<k;j++)
 6         if(x[j]==x[k])
 7             return false;
 8     return true;
 9 }
10 void backtrack(int t,int cost[][20+1],int n,int x[],int money){
11     if(t>n){
12         if(best>money)
13             best=money;//money为当前的花费,best为目前最优解 
14         return ;
15     }
16     else{
17         for(int i=1;i<=n;i++){
18         x[t]=i;
19         if(bound(t,x)&&money<best){
20             money+=cost[t][i];
21     //        cout<<money<<endl;
22             backtrack(t+1,cost,n,x,money);
23             money-=cost[t][i];
24     //        cout<<money<<endl;
25             }
26         }
27     }
28 }
29 int main(){
30     int n;
31     cin>>n;
32     int cost[n+1][20+1]; 
33     for(int i=1;i<=n;i++)
34         for(int j=1;j<=n;j++)
35             cin>>cost[i][j];
36     int x[n+1];
37     int money=0;
38     backtrack(1,cost,n,x,money); 
39     cout<<best;
40     return 0;
41 } 

 

心得体会:

  回溯最大的问题,就是知道怎么写解空间树,不知道怎么用代码来写。。另外,c++学会class什么的真的买不了吃亏买不了上当,没看我传值快传疯了吗。

 

posted @ 2018-12-20 00:42  GYRY  阅读(128)  评论(0编辑  收藏  举报