Given 2N people, you need to assign each of them into either red team or white team such that each team consists of exactly N people and the total competitive value is maximized.
给定2N个人,你需要去把他们分配到红队或者白队里,使得每一个队伍都有n个人,以及仇恨值最大
Total competitive value is the summation of competitive value of each pair of people in different team.
仇恨值就是在不同队伍里每一对人的仇恨值之和
The equivalent equation is ∑2Ni=1(vij if i-th person is not in the same team as j-th person else 0)∑i=12N∑j=i+12N(vij if i-th person is not in the same team as j-th person else 0)
输入描述:
The first line of input contains an integers N.
Following 2N lines each contains 2N space-separated integers vijvij is the j-th value of the i-th line which indicates the competitive value of person i and person j.
* 1≤N≤141≤N≤14
* 0≤vij≤1090≤vij≤109
* vij=vjivij=vji
输出描述:
Output one line containing an integer representing the maximum possible total competitive value.
本题可以直接使用DFS,策略是在搜索中分别用数组模拟两个队伍,并模拟此人加入队伍,再计算仇恨值。
//#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 33;
inline ll lldcin()
{
ll tmp = 0, si = 1;
char c;
c = getchar();
while (c > '9' || c < '0')
{
if (c == '-')
si = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
tmp = tmp * 10 + c - '0';
c = getchar();
}
return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
ll totality1, totality2,finans;
ll n;
ll secq1[50], secq2[50],relationships[50][50];
void dfs(ll tmpans, ll current,ll limit1,ll limit2)
{
if (limit1 == n && limit2 == n)//如果满足条件
{
finans = max(finans, tmpans);
return;
}
if (limit1 < n)
{
ll increment = 0;
secq1[++limit1] = current;//模拟加入队伍
for (int i = 1; i <= limit2; i++)
increment += relationships[current][secq2[i]];//加入队伍后带来的仇恨值增量
dfs(tmpans + increment, current + 1, limit1, limit2);//继续
limit1--;//将此人逐出队伍,即回溯
}
if (limit2 < n)
{
ll increment = 0;
secq2[++limit2] = current;
for (int i = 1; i <= limit1; i++)
increment += relationships[current][secq1[i]];
dfs(tmpans + increment, current + 1, limit1, limit2);
limit2--;
}
}
int DETERMINATION()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
n <<= 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> relationships[i][j];
n >>= 1;
dfs(0, 1, 0, 0);
cout << finans << endl;
return 0;
}