題目連結
大概題意是有n個男的n個女的(原諒我這麼說,我是粗人),給你一個n*n的矩陣,第i行第j列表示第i個女(男)對第j個男(女)的好感度,然後要安排n對相親,保證都是正常的(無搞基百合之類的),然後求怎麼安排能使好感度和最大,求出最大值。
開始試了純暴力的方法,時間複雜度是n!果斷逾時
#include <iostream>#include <string.h>#include <algorithm>using namespace std;int vis[17];int n, ans, sum;int map[19][19];void dfs(int x){ if (x == n+1) { ans = max(ans, sum); return; } for (int i = 1; i <= n; i++) { if (vis[i] == 0) { sum += map[x][i]; vis[i] = 1; dfs(x+1); vis[i] = 0; sum -= map[x][i]; } }}int main(){ int t; cin >> t; for (int kase = 1; kase <= t; kase++) { cin >> n; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> map[i][j]; sum = 0; ans = 0; memset(vis, 0, sizeof(vis)); dfs(1); cout << "Case " << kase << ": " << ans << endl; } return 0;}
後來因為一個小小的弱智的錯誤 wa了5 6次。代碼中用了很多位元運算,通過位元運算很方便的把狀態進行了壓縮儲存起來。
//2013-06-25-22.05#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>using namespace std;const int maxn = 1<<16;int vis[17];int n, ans, sum;int map[19][19];int dp[maxn];int dfs(int x, int d){ if (x == 0) return 0; if (dp[x]) return dp[x]; for (int i = 0; i < n; i++) { if (x&(1<<i)) dp[x] = max(dfs(x^(1<<i), d-1)+map[i+1][d], dp[x]); } return dp[x];}int main(){ int t; cin >> t; for (int kase = 1; kase <= t; kase++) { cin >> n; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> map[i][j]; memset(dp, 0, sizeof(dp)); ans = dfs((1<<n)-1, n); printf("Case %d: %d\n", kase, ans); } return 0;}