1. 程式人生 > >演算法第五章上機實踐報告

演算法第五章上機實踐報告

一、實踐題目:工作分配問題

二、問題描述:

       將現有的 件工作分配給 個人。已知將工作 分配給第 個人所需的費用為 cij 。對於給定的工作費用,為每一個人分配一件不同的工作,並使總費用達到最小。可將問題轉化為找到一個排列,使得 cij 的和最小,即排列樹問題。

三、演算法描述:

       ①解空間:類似於旅行售貨員問題的一顆排列樹。

       ②解空間樹:(設 

=3)

       ③限界演算法描述:

              在當前情況的費用和 v 小於當前的最優解 ans 時,才進行下一層的遞迴。即 if (v<ans) dfs(x+1);

程式碼如下:

 

#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 1e3+5;
int n;
int num[maxn], c[maxn][maxn];
int ans = 1e9, v = 0;

void dfs(int x){
	if(x>n){
		if(v<ans){
			ans = v;
		}
		return ;
	}
	
	for(int i = x; i <= n; ++i){
		swap(num[i], num[x]);
		v+=c[x][num[x]];
		if(v<ans) dfs(x+1);
		v-=c[x][num[x]];
		swap(num[i], num[x]);
	}
}

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		num[i] = i;
		for(int j = 1; j <= n; ++j){
			scanf("%d", &c[i][j]);
		}
	}
	dfs(1);
	printf("%d", ans);
	return 0;
}

 

四、心得體會

       和隊友這道題目是我跟隊友一起解決的,開始因為回溯的程式碼寫的有問題,乾脆直接寫成了一個暴力,雖然通過了但是並沒有達到實踐目的。之後又討論了一下,重新整理了一下思路,發現是將本該填x的地方填成了i,改了之後就可以通過了。這道題讓我們對回溯法有了進一步的瞭解,加深了印象。