题目描述
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.
Total competitive value is the summation of competitive value of each pair of people in different team.
The equivalent equation is ∑2Ni=1∑2Nj=i+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 vij is the j-th value of the i-th line which indicates the competitive value of person i and person j.
- 1≤N≤14
- 0≤vij≤109
- vij=vji 输出描述:
Output one line containing an integer representing the maximum possible total competitive value.
示例1
输入
1
0 3
3 0输出
3
本题的意思大致上是指:
将2N个人分为为两个小队,每队N人,每两个人之间都有一个竞争值,当两人分在一个队伍时,当然没有竞争,两者竞争值为0,不在一个队伍时,他们之间的竞争值该是多少就是多少。最后求最大竞争值总和分组的竞争值(即怎样分组时竞争值总和最大,输出最大值)。
输入:N,2N*2N的矩阵,其中矩阵中i行j列的值和j行i列的竞争值相等。
思路:模拟所有情况,求出最大值。
#include"iostream"
using namespace std;
typedef long long ll;
ll N,rn = 0 ,bn = 0,a[30][30],r[30],b[30],ans = 0;//a为竞争值数组,r,b分别存两个队伍中的人,rn,bn分别为对应队伍人数
void dfs(ll n,ll sum){
if(rn==N||bn==N){//当一个队伍分好,另一个队伍也默认分好了,就可以直接求出竞争值,不用继续分
if(rn==N){
for(ll i = n;i <= 2*N;i++)
for(ll j = 1;j <= rn;j++)
sum+=a[i][r[j]];
}
else{
for(ll i = n;i <= 2*N;i++)
for(ll j = 1;j <= bn;j++)
sum+=a[i][b[j]];
}
ans = max(ans,sum);
return;
}
r[++rn] = n;//注意在n分在r队后,再讨论将n分在b队前,要还原
ll temp = 0;
for(ll i = 1;i <= bn;i++)
temp+=a[n][b[i]];
dfs(n+1,sum+temp);
temp = 0;//还原
rn--;//还原
b[++bn] = n;
for(ll i = 1;i <= rn;i++)
temp+=a[n][r[i]];
dfs(n+1,sum+temp);
bn--;
}
int main(){
cin >> N;
for(ll i = 1;i <= 2*N;i++)
for(ll j = 1;j <= 2*N;j++)
cin >> a[i][j];
dfs(1,0);
cout << ans;
return 0;
}