1. 程式人生 > >回溯法求工作分配問題

回溯法求工作分配問題

首先,這個問題是個基本的回溯問題,我想說的重要的一點就是,在深搜過程中,如果中途遇到部分值已經大於前面所得的最小值,此時應該省去後面部分的計算,這對於演算法的執行時間會產生很大的影響,我已開始沒有考慮這些,就有四個樣例始終超時!!!

題目如下:

有 n 份工作要分配給 n 個人來完成,每個人完成一份。第 i 個人完成第 k 份工作所用的時間為一個正整數 tik,其中1 ≤ i, k ≤ n。試確定一個分配方案,使得完成這 n 份工作的時間總和最小。

輸入

輸入包含 n + 1 行。

第 1 行為一個正整數 n。

第 2 行到第 n + 1 行中每行都包含 n 個正整數,形成了一個 n × n 的矩陣。在該矩陣中,第 i 行第 k 列元素 tik 表示第 i 個人完成第 k 件工作所要用的時間。

輸出

1 行,包含一個正整數,表示所有分配方案中最小的時間總和。

輸入樣例

5
9 2 9 1 9
1 9 8 9 6
9 9 9 9 1
8 8 1 8 4
9 1 7 8 9

輸出樣例

5

限制

1 ≤ n ≤ 15

1 ≤ tik ≤ 10^4

#include <iostream>

using namespace std;
int N;
int people_work[15][15];
int vis[15]={0};
int cur[15];
int min_time;
int total=0;
void cal_min_time(int num){
    if(num==N){
        if(min_time==-1||total<min_time){
            min_time=total;
        }
    }
    else{
        for(int i=0;i<N;i++){
            if(!vis[i]){
                total+=people_work[num][i];
                if(min_time!=-1&&total>min_time){
                    total-=people_work[num][i];
                    continue;
                }
                vis[i]=1;
                cal_min_time(num+1);
                total-=people_work[num][i];
                vis[i]=0;
            }
        }
    }
}
int main()
{
    cin>>N;
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            cin>>people_work[i][j];
        }
    }
    min_time=-1;
    cal_min_time(0);
    cout<<min_time;
    return 0;
}