题意:有2*N个人,分成两队,每组n个人,求一个组中所有人和另外一组的所有人的竞争值之和。
比赛时没看懂题目+以为是什么高深难题=没做出来。。。
后面看了题解才发现,暴力枚举就可以过了。。。。
先将所有人归为1队,总竞争值为0,接下来从里面挑选出n个人,求最大竞争值。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=155;
typedef long long ll;
ll map[30][30];
ll ans,temp;
bool vis[30]={0};
void cator(int pos,int num,int n) //pos为当前位置,num为已分好的人数,n为总人数
{
//cout<<temp<<' '<<num<<endl;
if(num==n/2)
{
ans=max(ans,temp);
return;
}
if(n-pos+1<n/2-num) return; //剪枝1,当前剩余人数小于还需分配的人数,返回
for(int i=pos;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
ll t=temp;
for(int j=1;j<=n;j++)
{
if(vis[j]) temp-=map[j][i];
else temp+=map[j][i];
}
cator(i+1,num+1,n);
vis[i]=0;
temp=t;
}
}
}
int main()
{
int n;
scanf("%d",&n);
n*=2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lld",&map[i][j]);
for(int i=1;i<=n;i++) //剪枝2,事先将1归入另一队(最重要!没了会TLE!)
temp+=map[1][i];
ans=0; vis[1]=1;
cator(2,1,n);
printf("%lld\n",ans);
return 0;
}