zoukankan      html  css  js  c++  java
  • NOIP2017 D2T3 题解

    题面

    这种数据范围不是乱搞dfs就是乱搞状压DP

    首先应该通过任一方式求出a和b的值;

    任意一条抛物线只用两头猪就可以确定,所以我们N^2枚举,并把在这两头猪的抛物线上的猪都存进状态state[i][j];

    然后枚举任意两个还没消灭的小猪i,j;f[i|state[j][k]]=min(f[i|state[j][k]],f[i]+1);

    因为有些小猪只能单独被消灭,所以:f[i|(1<<j-1)]=min(f[i|(1<<j-1)],f[i]+1);

    然后就好了:

    #include <bits/stdc++.h>
    #define eps 1e-7
    #define inc(i,a,b) for(register int i=a;i<=b;i++)
    using namespace std;
    struct node{
    	double x;
    	double y;
    }pig[20];
    int f[1000010];
    int bo[21];
    int n,m;
    int work(int pig1,int pig2)
    {
    	if(pig[pig1].x==pig[pig2].x) return 0;
    	double x1=pig[pig1].x,x2=pig[pig2].x,y1=pig[pig1].y,y2=pig[pig2].y;
    	double tmpx=x1*x1*x2-x2*x2*x1,tmpy=y1*x2-y2*x1;
    	double a=tmpy/tmpx,b=(y1-a*x1*x1)/x1;
    	if(a>=0) return 0;
    	int res=0;  bo[pig1]=bo[pig2]=1;
    	inc(i,1,n){
            double x=pig[i].x,y=pig[i].y;
            if(fabs(a*x*x+b*x-y)<eps) res|=1<<(i-1),f[1<<(i-1)]=f[res]=1;
        }
        return res;
    }
    int state[110][110];
    int main()
    {
    	int t;
    	cin>>t;
    	while(t--){
    		memset(f,0x3f,sizeof(f));
    		memset(state,0,sizeof(state));
    		memset(bo,0,sizeof(bo));
    		scanf("%d%d",&n,&m);
    		inc(i,1,n) scanf("%lf%lf",&pig[i].x,&pig[i].y),f[1<<i-1]=1;
    		inc(i,1,n) inc(j,1,i-1) state[i][j]=work(i,j);
    		inc(i,1,(1<<n)-1) inc(j,1,n){
    			if((i>>j-1)&1==1)continue;
    			inc(k,1,j-1){
                   if(i&(1<<k-1)==1) continue;
                   f[i|state[j][k]]=min(f[i|state[j][k]],f[i]+1);
                }
                f[i|(1<<j-1)]=min(f[i|(1<<j-1)],f[i]+1);
    		}
    		cout<<f[(1<<n)-1]<<endl;
    	}
    }
    
  • 相关阅读:
    Linux下MySQL主从同步配置
    Tortoisegit图文使用教程
    C语言I博客作业06
    第十周助教总结
    C语言I博客作业04
    C语言I博客作业02
    第十一周助教总结
    第十二周助教总结
    第九周助教总结
    C语言I博客作业02
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11728564.html
Copyright © 2011-2022 走看看