P2924 Largest Fence G

鸡脚排序简单题

1.P2924 Largest Fence G

题目描述

Farmer John的农场里有N(5<=N<=250)个篱笆桩,每个都有独一无二的坐标(xi,yi)(1<=xi,yi<=1000)。他想选择尽量多的篱笆桩来构建他的围栏。这个围栏要美观,所以必须是凸多边形的。那他最多能选多少个呢?

所有的篱笆桩中不存在三点共线。

题目分析

根据凸包的性质可以知道,凸包的所有边拉出来都是按照极角序有单调性的,那么枚举所有的起点,进行一下对于所有可能边的dp就行了

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
// Created by mrx on 2022/11/7.
//
#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <cmath>
#include <queue>
#include <array>
#include <map>

using i64 = long long;
constexpr double eps = 1e-6;

int sgn(double x) {
return x < -eps ? -1 : x > eps;
}

int sgn(i64 x) {
return x < 0 ? -1 : x > 0;
}

template<typename T>
struct Point {
T x, y;

template<class Y>
Point(const Point<Y>& cp):x(cp.x), y(cp.y) {}

Point() : x(0), y(0) {}

Point(T _x, T _y) : x(_x), y(_y) {}

friend std::istream& operator >>(std::istream& is, Point& rhs) { return is >> rhs.x >> rhs.y; }

friend std::ostream& operator <<(std::ostream& os, const Point& rhs) { return os << '(' << rhs.x << ',' << rhs.y << ')'; }

Point operator -(const Point& rhs) const { return {x - rhs.x, y - rhs.y}; }

Point& operator -=(const Point& rhs) { return (*this) = (*this) - rhs; }

Point operator +(const Point& rhs) const { return {x + rhs.x, y + rhs.y}; }

Point& operator +=(const Point& rhs) { return (*this) = (*this) + rhs; }

template<class Y>
Point<double> operator *(const Y& rhs) const { return {x * rhs, y * rhs}; }

template<class Y>
Point<double> operator /(const Y& rhs) { return {x / rhs, y / rhs}; }

friend double abs(const Point& lhs) { return std::sqrt(lhs.x * lhs.x + lhs.y * lhs.y); }

friend i64 abs2(const Point& lhs) { return (lhs.x * lhs.x + lhs.y * lhs.y); }

friend T cross(const Point& lhs, const Point& rhs) { return lhs.x * rhs.y - lhs.y * rhs.x; }

friend T dot(const Point& lhs, const Point& rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; }

friend double angle(const Point& rhs) { return atan2(rhs.x, rhs.y); }

Point rotate90() const { return {y, x}; }

Point<double> rotate(double deg) { return {x * cos(deg) - y * sin(deg), x * sin(deg) + y * cos(deg)}; }

bool operator <(const Point& rhs) const { return sgn(x - rhs.x) == 0 ? sgn(y - rhs.y) < 0 : sgn(x - rhs.x) < 0; }

bool operator ==(const Point& rhs) const { return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0; }

bool up() const { return sgn(y) == 0 ? sgn(x) >= 0 : sgn(y) > 0; }
};

using Pl = Point<i64>;

std::vector<Pl> ConvexHull(std::vector<Pl> points) {
int n = points.size();
std::sort(points.begin(), points.end());
for (auto x: points)std::cout << x << '\n';
std::deque<Pl> dq;

for (auto& point: points) {
while (dq.size() > 1 && sgn(cross(dq[dq.size() - 1] - dq[dq.size() - 2], point - dq[dq.size() - 2])) < 0)dq.pop_back();
dq.push_back(point);
}
for (auto x: dq)std::cerr << x << '\n';

int k = int(dq.size());
for (int i = n - 1; i >= 0; i--) {
while (dq.size() > k && sgn(cross(dq[dq.size() - 1] - dq[dq.size() - 2], points[i] - dq[dq.size() - 2])) < 0)dq.pop_back();
dq.push_back(points[i]);
}

std::vector<Pl> ans(dq.begin(), dq.end());
return ans;
}

int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);

int n;
std::cin >> n;
std::vector<Pl> points(n);
for (int i = 0; i < n; ++i)std::cin >> points[i];

std::vector<std::pair<int, int>> e;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == j)continue;
e.emplace_back(i, j);
}
}

std::sort(e.begin(), e.end(), [&](auto x, auto y) {
Pl v1 = points[x.first] - points[x.second];
Pl v2 = points[y.first] - points[y.second];
return v1.up() ^ v2.up() ? v1.up() > v2.up() : cross(v1, v2) < 0;
});
// for (auto x: e)std::cout << points[x.first] - points[x.second] << '\n';

int ans = 0;

for (int i = 0; i < n; ++i) {

std::vector<int> dp(n, -0x3f3f3f3f);
dp[i] = 0;
for (auto [l, r]: e) {
dp[r] = std::max(dp[r], dp[l] + 1);
// std::cerr << l << ' ' << r << ' ' << dp[r] << '\n';
}
// std::cerr << "!!!!" << dp[i] << '\n';
ans = std::max(ans, dp[i]);
}

std::cout << ans << '\n';

return 0;
}

P2924 Largest Fence G
https://mrxyan6.github.io/2022/11/07/P2924/
作者
mrx
发布于
2022年11月7日
许可协议