题面
题解
好像昨天wxl大爷讲的是O(Tn*2^n)的做法,后来没想通,就自己写了个O(Tn^2*2^n)的暴力状压,
莫名其妙过了??数量级二十亿??懵逼,可能到了CCF老爷机上就T了。dp[S]表示现在猪的状态,
然后枚举两只鸟,然后开炮。
代码
#include<bits/stdc++.h>
using namespace std ;
const int MAXN = 18 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
struct PIG{
double x,y;
}p[20 ];
int cnt;
int n,m,T,S,pre;
int dp[1 <<MAXN];
double a,b;
int main(){
scanf ("%d" ,&T);
while (T--){
memset (dp,0x3f ,sizeof (dp));
dp[0 ]=0 ;
scanf ("%d%d" ,&n,&m);
for (register int i=1 ;i<=n;i++)
scanf ("%lf%lf" ,&p[i].x,&p[i].y);
for (register int i=0 ;i<((1 <<n)-1 );i++){
S=0 ;a=0 ;b=0 ;pre=0 ;
if (dp[i]==inf) continue ;
for (register int j=1 ;j<=n;j++){
S=0 ;pre=0 ;a=0 ;b=0 ;
if ((i&(1 <<(j-1 )))==0 ){
S|=(1 <<(j-1 ));
pre=j;
}
if (!pre) continue ;
for (register int k=1 ;k<=n;k++)
if ((i&(1 <<(k-1 )))==0 && k!=j)
if (p[pre].x!=p[k].x){
a=p[pre].y*p[k].x/p[pre].x-p[k].y;
a/=(p[pre].x*p[k].x-p[k].x*p[k].x);
if (a>=0 ) continue ;
else {
b=(p[pre].y-a*p[pre].x*p[pre].x)/p[pre].x;
break ;
}
}
if (a<0 )
for (register int j=1 ;j<=n;j++)
if (fabs (a*p[j].x*p[j].x+b*p[j].x-p[j].y)<=eps && j!=pre)
S|=(1 <<(j-1 ));
dp[S|i]=min(dp[S|i],dp[i]+1 );
}
}
printf ("%d\n" ,dp[(1 <<n)-1 ]);
}
}