题意:
给你一个图,图中任意两点的距离都给你了。然后让你把这个图的所有的点分成两个子集。
要求两个子集之间的所有点的距离和最大。
做法:
题目数据小,n《=20,所以依次枚举一个子集中有1~20个元素的情况。
对于每种情况,距离等于一个子集中的点,到其他任意点的距离和减去子集中任意两点的距离和
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int map[21][21];
int len[21];
int n;
int maxx;
int maxxsize;
int visit[25];
int vis_num=0;
void find(int now,int x)
{
// printf("&&%d,max=%d,maxsize=%d\n",vis_num,maxx,maxxsize);
int i,j,k;
if(x==0)
{
if(maxxsize<maxx)
maxxsize=maxx;
return ;
}
int maxy;
for(i=now;i<=n;i++)
{
maxy=maxx;
maxx+=len[i];
for(j=0;j<vis_num;j++)
{
k=visit[j];
maxx-=2*map[i][k];
}
visit[vis_num++]=i;
// printf("**********\n");
// printf("++%d\n",i);
find(i+1,x-1);
// printf("--%d\n",i);
vis_num--;
maxx=maxy;
}
}
int main()
{
int i,j;
cin>>n;
maxx=0;
maxxsize=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
}
}
int num;
for(i=1;i<=n;i++)
{
num=0;
for(j=1;j<=n;j++)
{
num+=map[i][j];
}
len[i]=num;
}
for(i=1;i<=n/2;i++)
{
// printf("!!!!!!!!!!!!!!!!!!!!!\n");
vis_num=0;
maxx=0;
find(1,i);//f(x,y),x表示从第几个点开始取数,y表示一共需要取多少个数放入一个子集里
}
printf("%d\n",maxxsize);
return 0;
}