再就业 | ||||||
| ||||||
Description | ||||||
修水管没修好,小胖子又失业了,于是又找了一份在婚姻介绍所的工作,现在老板又给小胖子出难题了,如果小胖子能解决,就可以重新再就业了。 这里有n对男女士,任意一个男生对一个女生都有一个好感值,任意一个女生也对一个男生有好感值,给出一个好感值表,为了方便,用n*n的矩阵表示,(i,j)表示第i行表示男士(或女士)对第j列的女士(或男士)的好感度,问怎么安排n对相亲才能使成功率最大,并且不存在搞基等事件发生。 小胖子感慨,没文化真可怕,工作都没了。 | ||||||
Input | ||||||
第一行输入一个整数t,代表测试次数,t不超过100。 对于每组数据的第一行输入一个整数n,代表有多少对男女生,n大于0不超过16。 接下来是一个n*n的矩阵,每个数字分别表示i和j之间的好感度,好感度不超过10000。 | ||||||
Output | ||||||
输出最大相亲的好感和。 | ||||||
Sample Input | ||||||
2 2 1 5 2 1 3 1 2 3 6 5 4 8 1 2 | ||||||
Sample Output | ||||||
7 | ||||||
Author | ||||||
sunshine@hrbust |
#include <bits/stdc++.h>
using namespace std;
const int N = 17;
int t, n;
int dp[N][1<<N];
int a[N][N];
int main(){
scanf("%d", &t);
while(t--){
scanf("%d", &n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &a[i][j]);
}
}
memset(dp, -1, sizeof(dp));
for(int i = 0; i < n; i++){
dp[0][1<<i] = a[0][i];
}
int m = 1<<n;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(dp[i][j] == -1) continue;
for(int k = 0; k < n; k++){
int tmp = 1<<k;
if(j&tmp) continue;
dp[i+1][j+tmp] = max(dp[i+1][j+tmp], dp[i][j] + a[i+1][k]);
}
}
}
int ans = 0;
for(int i = 0; i < m; i++){
ans = max(ans, dp[n-1][i]);
}
printf("%d\n", ans);
}
}