zoukankan      html  css  js  c++  java
  • LG2831 愤怒的小鸟

    题意

    分析

    看n的范围只有18,考虑状压dp。

    (f(s))表示过集合s中的点所需最小的抛物线数量。

    然后枚举点对算抛物线,判断其他点是否在抛物线上来转移。

    细节

    判断能否构成抛物线只需要判断斜率关系,具体来说是

    [frac{y_i}{x_i} > frac{y_j-y_i}{x_j-x_i} ]

    判断三点是否在同一抛物线上,考虑方程

    [left{ egin{array}{} a x_i^2 + bx_i & = & y_i \ a x_j^2 + bx_j & = & y_j \ a x_k^2 + bx_k & = & y_k \ end{array} ight. ]

    有解的条件是矩阵

    [left[ egin{matrix} x_i^2 & x_i & y_i \ x_j^2 & x_j & y_j \ x_k^2 & x_k & y_k end{matrix} ight] ]

    线性相关,只需行列式为0。(B君太优秀了。)

    代码

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #define rg register
    #define il inline
    #define co const
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> il T read(rg T&x)
    {
        rg T data=0;
    	rg int w=1;
        rg char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=20;
    int n,m,ms;
    ll x[MAXN],y[MAXN];
    
    int f[1<<MAXN|7];
    
    il void update(rg co int&x)
    {
    	for(rg int i=0;i<=ms;++i)
    	{
    		f[i|x]=min(f[i|x],f[i]+1);
    //		cerr<<(i|x)<<" f="<<f[i|x]<<" fi+1="<<f[i]+1<<" min="<<min(f[i|x],f[i]+1)<<endl;
    	}
    		
    }
    
    il bool in(rg co int&i,rg co int&j,rg co int&k)
    {
    	rg ll det=0;
    	det += x[i] * x[i] * x[j] * y[k];
    	det += x[i] * y[j] * x[k] * x[k];
    	det += y[i] * x[j] * x[j] * x[k];
    	det -= y[i] * x[j] * x[k] * x[k];
    	det -= x[i] * x[j] * x[j] * y[k];
    	det -= x[i] * x[i] * y[j] * x[k];
    	return det==0;
    }
    
    int main()
    {
    //  freopen(".in","r",stdin);
    //  freopen(".out","w",stdout);
    	rg int T;
    	read(T);
    	while(T--)
    	{
    		memset(f,0x3f,sizeof f);
    		f[0]=0; // edit 1:the init of f
    		
    		read(n);read(m);
    		ms=(1<<n)-1;
    		for(rg int i=0;i<n;++i)
    		{
    			rg double xi,yi;
    			scanf("%lf %lf",&xi,&yi);
    			x[i] = ll(100 * xi + 0.5);
    			y[i] = ll(100 * yi + 0.5);
    //			cerr<<i<<" x="<<x[i]<<" y="<<y[i]<<endl;
    		}
    		
    		for(rg int i=0;i<n;++i)
    		{
    			update(1<<i);
    			for(rg int j=0;j<n;++j)
    				if(x[j] > x[i] && y[i] * (x[j] - x[i]) > x[i] * (y[j] - y[i]))
    				{
    					rg int s=(1<<i)|(1<<j);
    					for(rg int k=0;k<n;++k)
    						if(in(i,j,k))
    							s|=(1<<k);
    //					cerr<<i<<" "<<j<<" s="<<s<<endl;
    					update(s);
    				}
    		}
    		
    /*		for(int i=0;i<1<<n;++i)
    			cerr<<i<<" f="<<f[i]<<endl;*/
    		
    		printf("%d
    ",f[ms]);
    	}
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    [原]Unity3D深入浅出
    SSH 远程端口转发
    SSH 本地端口转发
    SSH执行远程命令和传送数据
  • 原文地址:https://www.cnblogs.com/autoint/p/9806711.html
Copyright © 2011-2022 走看看