• #4719. 内凸包


    题目描述

    已知平面上 $n$ 个点,称点集 $S$ 是内凸包,当且仅当:
    - $S$ 是某个点集的凸包;
    - 设 $S$ 构成的凸多边形为 $G$,则 $S$ 以外的点要么在 $G$ 的边上,要么在 $G$ 外.

    试最大化内凸包构成的凸多边形的面积。

    题解

    首先我们考虑枚举点 $O$ 作为凸包最下方的点,然后取出它上方的点按极角排序。因为我们是按照极角顺序取点的,所以我们可以设计 $ ext{dp}$ : $f[i][j]$ 表示凸包最后一个点为 $i$ ,其次为 $j$ 的最大面积,我们可以得到转移式: $f[i][j]=max{f[j][k]+S(O,i,j)}$ ,其中 $k<j$ , $Oij$ 中没有其它点且 $k$ 在 $(i,j)$ 下方。这样是 $O(n^4)$ 的,过不去。

    考虑优化,我们可以发现对于 $i$ 来说,从 $Oi$ 开始,找到极角最大的 $j$ 在 $Oi$ 下方,然后将 $O$ 设为 $i$ , $i$ 设为 $j$ 接着找,这些点才会满足 $Oij$ 内没有别的点,然后我们设 $g[i][j]=max{f[i][k]}$ ,其中 $k<j$ 且 $k$ 是那些点中的一个,所以对于找到的点 $j$ , $f[i][j]=S(O,i,j)+g[j][next[j]]$ 。这样做就是 $O(n^3)$ 的了。

    主要是考察凸包的构建过程,不应该没思路。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int T,n,m,s,f[55][55],c[55];
    struct O{int x,y;}b[55],a[55];
    O operator -(O A,O B){
        return (O){A.x-B.x,A.y-B.y};
    }
    int operator *(O A,O B){
        return A.x*B.y-A.y*B.x;
    }
    int S(O A){
        return A.x*A.x+A.y*A.y;
    }
    bool cmp(O A,O B){
        return A*B<0 || (A*B==0 && S(A)<S(B));
    }
    void W(){
        memset(f,0,sizeof f);
        sort(a+1,a+m+1,cmp);
        for (int j,k,t,v,i=2;i<=m;i++){
            j=i-1;t=0;
            while(j && a[j]*a[i]==0) j--;
            while(j){
                c[++t]=j;k=j-1;v=a[i]*a[j];
                while(k && (a[k]-a[j])*(a[i]-a[j])<0) k--;
                if (k) v+=f[j][k];
                f[i][j]=v;s=max(v,s);j=k;
            }
            for (int u=t-1;u>0;u--)
                f[i][c[u]]=max(f[i][c[u]],f[i][c[u+1]]);
        }
    }
    void work(){
        scanf("%d",&n);s=0;
        for (int i=1;i<=n;i++)
            scanf("%d%d",&b[i].x,&b[i].y);
        for (int i=1;i<=n;i++){
            m=0;
            for (int j=1;j<=n;j++){
                if (b[j].y>b[i].y || (b[j].y==b[i].y && b[j].x>b[i].x))
                    a[++m]=b[j]-b[i];
            }
            W();
        }
        printf("%.1lf
    ",1.*s/2);
    }
    int main(){for (cin>>T;T--;work());return 0;}
  • 相关阅读:
    构建CMDB的一些启发
    一个NB的安全认证机制
    SQLAlchemy
    Tornado基本使用
    Tornado源码探寻(请求到来)
    Tornado源码探寻(准备阶段)
    Tornado源码探寻(开篇)
    我的个人博客网站
    IDEA/AS快捷键收集&习惯
    ubuntu命令收集
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12332741.html
Copyright © 2020-2023  润新知