此页面通过工具从 csdn 导出,格式可能有问题。
以前就开始看刘汝佳的白皮书了,不过眼高手低,没有码过,发现问题好多。于是开始敲一敲。
题意:
空间有n个点,分成n/2对,使得所有点集的两点之间的距离之和最小。
d(s) = min{ d(s-i-j) } i,j 属于 s
PS:只有20个点,每个点可以取可以不取,所以用20位的二进制数来表示每个状态。
要注意的是,i,j 是不需要一个一个都枚举的,会有重复。比如1234会有12+34,又会有34+12造成浪费。如果是123456就会浪费更多。可以假设最小的1是当前取得,那么只要 找 12,13,14,15,16 。
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
typedef struct{
int x,y,z;
}NODE;
NODE g[22];
int n,k;
double d[1<<22];
double dis(int i,int j){
NODE a(g[i]), b(g[j]);
return sqrt(((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)));
}
int main(){
cin >> n;
for (int i(0);i<n;i++)
cin >> g[i].x >> g[i].y >> g[i].z;
for ( int i(1);i<(1<<n);i++){
d[i] = 1e10;
int k;
for (k=0;k<n;k++)
if ( i & (1<<k) ) break;
for (int j(k+1);j<n;j++)
if (i & (1<<j))
d[i] = min(d[i],dis(k,j)+d[i^(1<<j)^(1<<k)]);
}
cout << d[(1<<n)-1] << endl;
return 0;
}