第五章實驗報告
阿新 • • 發佈:2018-12-20
實踐題目:
工作分配問題
問題描述:
設有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]) 7return 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什麼的真的買不了吃虧買不了上當,沒看我傳值快傳瘋了嗎。