• [usaco] 2008 Dec Largetst Fence 最大的围栏 2 || dp


    原网站大概已经上不了了……

    题目大意:
    求出平面上n个点组成的一个包含顶点数最多的凸多边形。n<=250.


    考虑我们每次枚举凸包的左下角为谁(参考Graham求凸包时的左下角),然后像Graham一样,将其他点相对于当前左下角做一个极角排序。
    我们会想到一个dp,dp[i][j]表示当前边为i到j的最多点,得到下面这样的转移:

    for (int i=1;i<=n;i++)
        if (x!=i) dp[x][i]=1;
    for (int i=1;i<=n;i++)
        for (int j=i+1;j<=n;j++)
            for (int k=1;k<i;k++)
                if (check(k,i,j)) dp[i][j]=max(dp[i][j],dp[k][i]+1);
    //check是检查是否为“凸”
    

    而这样就是n^4了,怎么优化呢?
    我们可以记录f[i]为dp[][i]的最大值,这样就省去了枚举k的n,就得到了n^3算法!
    因为要省去枚举k的过程,所以check怎么办?
    我们预处理每条线段,然后将线段按极角排序即可~

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 300
    using namespace std;
    int n,q[N],f[N],dp[N][N],num,ans;
    struct hhh
    {
    	int x,y;
    	hhh() : x(0),y(0) {}
    	hhh(int _x,int _y) : x(_x),y(_y) {}
    	hhh operator - (const hhh &b) const
    	{
    		return hhh(x-b.x,y-b.y);
    	}
    	int operator * (const hhh &b) const
    	{
    		return x*b.y-y*b.x;
    	}
    }a[N];
    struct hh
    {
    	hhh qwq;
    	int a,b;
    	bool operator < (const hh &b) const
    	{
    		return qwq*b.qwq<0;
    	}
    }v[N*N];
    
    int read()
    {
    	int ans=0,fu=1;
    	char j=getchar();
    	for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
    	for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
    	return ans*fu;
    }
    
    int check(int x)
    {
    	memset(f,128,sizeof(f));
    	memset(dp,0,sizeof(dp));
    	f[x]=0;
    	int QwQ=0;
    	for (int i=1;i<=num;i++)
    	{
    		dp[v[i].a][v[i].b]=max(dp[v[i].a][v[i].b],f[v[i].a]+1);
    		if (v[i].b!=x) f[v[i].b]=max(f[v[i].b],f[v[i].a]+1);
    	}
    	for (int i=1;i<=n;i++)
    		QwQ=max(QwQ,dp[i][x]);
    	return QwQ;
    }
    
    int main()
    {
    	freopen("dot.in","r",stdin);
    	freopen("dot.out","w",stdout);
    	n=read();
    	for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			if (i!=j)
    				v[++num].qwq=a[i]-a[j],v[num].a=i,v[num].b=j;
    	sort(v+1,v+num+1);
    	for (int i=1;i<=n;i++)
    		ans=max(ans,check(i));
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Java weak reference
    Java 代理模式
    Eclipse 代码自动提示
    Eclipse 设置默认编码为Utf-8
    MyBatis 作用域(Scope)和生命周期
    MyBatis 命名空间与命名解析
    Java 泛型 介绍
    【总结】过去的风口让很多人改变了阶层,我们90后的下一个风口会是什么?
    【前端】js截取or分割字符串的常见方法
    基于react/vue的移动端终极适配方案vw单位(更新css-modules配置)
  • 原文地址:https://www.cnblogs.com/mrha/p/8392483.html
Copyright © 2020-2023  润新知