設有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)。