链接:https://ac.nowcoder.com/acm/contest/882/F
来源:牛客网
题目描述
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 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.
示例1
输入
复制
1 0 3 3 0
输出
复制
3
题目大意:给你一个N,现在有2*N个人,你要做的就是把这2*N个人分成两队一队N个人,下面会给一个表,也就是每个人对其他人的作用,你要做的就是保证两个队伍作用的最大值,队伍作用的最大值是每个人对另一支队伍的作用的和
思路:这个题目当时做的时候没有做出来,后来看了有人过了的代码才做出来的,发现好像没有那么难的,
首先要明白每一个人一定会属于一个队伍,而且队伍名字的互换并不会产生任何影响,那么不妨假设1号在A队(这里我们把队伍分为AB两队)
然后就是暴力的搜索,对于我查过的区间就不要再去查,对于新进的编号,如果他本身就属于队伍A,那么你的队伍A的作用就要减去新进编号对之前A队伍的作用,加上新进编号对队伍B的作用,在A队数量满足题意时拉出来判断就好,最后做一个剪枝,详情见代码吧,有一定注释的
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=30;
ll a[maxn][maxn];
ll ans=0;
int n;
/*
mit 我们用二进制的位来表示2*n个人,第i位为1则i在A中
num 队伍A的人数
pre 我们是从前往后暴力查找所以就不用管前面的,
ans2 当前的答案
*/
void DFS(int mit,int num,int pre,ll ans2)
{
//cout<<"num:"<<num<<endl;
if(num==n/2)
{
ans=max(ans,ans2);
return ;
}
if(n/2<pre-num) return ;
for(int i=pre+1;i<=n;i++)//往后找
{
ll t=ans2;
for(int j=1;j<=n;j++)//判断一下新进编号对于其他编号的作用
{
if((mit>>j)&1)
t-=a[i][j];
else
t+=a[i][j];
}
DFS(mit|(1<<i),num+1,i,t);
}
}
int main()
{
scanf("%d",&n);
n*=2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lld",&a[i][j]);
ll temp=0;
for(int i=1;i<=n;i++)//我们假设1号已经在A队中
temp+=a[1][i];
//cout<<n<<" "<<temp<<endl;
DFS(2,1,1,temp);
printf("%lld\n",ans);
}