演算法第五章上機實踐報告
阿新 • • 發佈:2018-12-21
一、實踐題目:工作分配問題
二、問題描述:
將現有的 n 件工作分配給 n 個人。已知將工作 i 分配給第 j 個人所需的費用為 cij 。對於給定的工作費用,為每一個人分配一件不同的工作,並使總費用達到最小。可將問題轉化為找到一個排列,使得 cij 的和最小,即排列樹問題。
三、演算法描述:
①解空間:類似於旅行售貨員問題的一顆排列樹。
②解空間樹:(設 n =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,改了之後就可以通過了。這道題讓我們對回溯法有了進一步的瞭解,加深了印象。