HDU - 6219 Empty Convex Polygons——dp+几何

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82830045

首先枚举最低点o,将纵坐标大于等于o的点极角排序,然后dp求解

设dp(i,j)为以oi为最后一条边,以oj为倒数第二条边的最大空凸包,转移方程为 dp[i][j] = max(dp[i][j], dp[j][k] + area);其中area为三角形oij的面积,k要小于j,注意oij要能形成三角形,三角形oij内无点(这里不考虑边上),边oj上无点,向量i->k在向量i->j右面保证凸性

注意用int就可以,最后除2就好

#include <bits/stdc++.h>
using namespace std;
struct Point {
    int x, y;
    Point(int xx=0, int yy=0):x(xx),y(yy){}
    Point operator + (const Point &rhs) { return Point(x+rhs.x, y+rhs.y); }
    Point operator - (const Point &rhs) { return Point(x-rhs.x, y-rhs.y); }
}p[100], t[100];
int Dot(Point a, Point b) { return a.x*b.x+a.y*b.y; }
int Cross(Point a, Point b) { return a.x*b.y-a.y*b.x; }
bool cmp1(const Point &a, const Point &b) { return (a.y!=b.y?a.y<b.y:a.x<b.x); }
bool cmp2(const Point &a, const Point &b) { return (Cross(a,b)==0?Dot(a,a)<Dot(b,b):Cross(a,b)>0); }
int T, n, m, dp[100][100], ans;
void solve() {
    for (int i = 0; i <= m; i++) for (int j = 0; j <= i; j++) dp[i][j] = 0;
    for (int i = 2; i <= m; i++) {
        for (int j = 1; j < i; j++) {
            if (Cross(t[i], t[j]) == 0) continue;
            bool emp = 1;
            for (int k = j + 1; k < i; k++) {
                if (Cross(t[k], t[i]) > 0 && Cross(t[j], t[k]) > 0 && Cross(t[i]-t[j], t[k]-t[j]) > 0) { emp = 0; break; }
            }
            if (!emp) continue;
            dp[i][j] = Cross(t[j], t[i]);
            if (Cross(t[j], t[j-1]) != 0) {
                for (int k = 0; k < j; k++) {
                    if (Cross(t[k]-t[i], t[j]-t[i]) > 0) dp[i][j] = max(dp[i][j], dp[j][k] + Cross(t[j], t[i]));
                }
            }
            ans = max(ans, dp[i][j]);
        }
    }
}
int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y);
        sort(p+1, p+1+n, cmp1);
        ans = 0;
        for (int i = 1; i <= n-2; i++, m = 0) {
            for (int j = i+1; j <= n; j++) t[++m] = p[j]-p[i];
            sort(t+1, t+1+m, cmp2);
            solve();
        }
        printf("%.1f\n", 1.0*ans/2.0);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82830045