题意:给定二维平面上N个点,N是偶数,限制让你两两连线,使得平行线对数最多。N<=16;
思路:N为16时,复杂度=15*13*11*9*7*5*3*1~=2e6;所以可以枚举所有情况,即搜索可以做。 注意是两两配对,没有不选的情况,不然复杂度很高。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 10;
int n, vis[20], ans;
pair<int, int> xiel[20][20];
struct node {
int x, y;
} no[N];
map<pair<int, int>, int> mp;
void dfs(int now) {
if(now == n + 1) {
int res = 0;
for(auto k : mp)
if(k.second > 1) {
int a = k.second;
res += (a * (a - 1) / 2);
}
ans = max(ans, res);
return;
}
if(!vis[now]) {
for(int i = now + 1; i <= n; i++)
if(!vis[i]) {
vis[i] = 1;
mp[xiel[now][i]]++;
dfs(now + 1);
mp[xiel[now][i]]--;
vis[i] = 0;
}
} else
dfs(now + 1);
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d%d", &no[i].x, &no[i].y);
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++) {//这个用数组代表相同斜率个数的方式值得借鉴
int dx = no[i].x - no[j].x, dy = no[i].y - no[j].y;
if(dx < 0)
dx = -dx, dy = -dy;
if(dx == 0)
dy = abs(dy);
int g = __gcd(dx, dy);
dx /= g, dy /= g;
xiel[i][j] = xiel[j][i] = make_pair(dx, dy);
}
dfs(1);
printf("%d\n", ans);
return 0;
}