1. 程式人生 > >第五章實驗報告

第五章實驗報告

實踐題目:

  工作分配問題

問題描述:

設有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什麼的真的買不了吃虧買不了上當,沒看我傳值快傳瘋了嗎。