7-2 工做分配問題 (20 分)

設有n件工做分配給n我的。將工做i分配給第j我的所需的費用爲cij 。 設計一個算法,對於給定的工做費用,爲每個人都分配1 件不一樣的工做,並使總費用達到最小。java

輸入格式:

輸入數據的第一行有1 個正整數n (1≤n≤20)。接下來的n行,每行n個數,表示工做費用。算法

輸出格式:

將計算出的最小總費用輸出到屏幕。數組

輸入樣例:

在這裏給出一組輸入。例如:設計

3
10 2 3
2 3 4
3 4 5

輸出樣例:

在這裏給出相應的輸出。例如:code

9

 

這裏一樣採用回溯法,以物品爲順序來選擇被安排的工人;其中數組a[][]的第一列留爲標記位,用來判斷工人是否被安排工做;經過判斷當前花費總時間是否仍小於最小值min來剪枝;具體代碼以下:ci

 
package 宿題;
import java.io.*;
 
public class Main {
  static int a[][];
  static int n;
  static int min=Integer.MAX_VALUE;
  public static void main(String args[])throws IOException{
    StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    in.nextToken();
    n=(int)in.nval;
    a=new int[n+1][n+1];
    for(int i=1;i<=n;i++){
      for(int j=1;j<=n;j++){
        in.nextToken();
        a[i][j]=(int)in.nval;
      }
    }
    Arrange(a,1,0);
    System.out.println(min);//輸出最小值;
  }
 
  private static void Arrange(int a[][],int i,int sum){
    if(i>n){//到達最後節點,比較最小值;
      if(sum<min)
        min=sum;
    }else{
      for(int I=1;I<=n;I++){//分爲和當前未分配工人數目一致個數的子結點;
        if(a[I][0]!=-1){//判斷當前工人是否被分配工做;
          a[I][0]=-1;//將當前未分配工人標記位改成-1,並進入子結點;
          if(sum+a[I][i]<min)//判斷子結點是否可能存在解,不然減去;
            Arrange(a,i+1,sum+a[I][i]);
          a[I][0]=0;//還原標記位,使其不影響相鄰結點;
        }
      }
    }
  }
 
}
 
該算法最壞狀況的時間複雜度爲O(2^n)。
相關文章
相關標籤/搜索