n好小啊,当时十分年轻地写了搜索,自己的数据跑得贼快,但是最终测评只有60+呀,不过,这数据范围,不应该一眼看出状压dp吗,而且还十分简单233。
考虑每一条抛物线,最多只能有n^2级的数量,还是很小的,可以承受,然后就是状态转移了,每条抛物线都可以转移一次。
大概的复杂度是O(n^2*2^n),还是轴对称的233。
#include<bits/stdc++.h>
using namespace std;
int T,m,n,tot,gun[500];
int f[262900];
double x[20],y[20],a,b;
bool kill(int id,double a,double b)
{
double val=a*x[id]*x[id]+b*x[id]-y[id];
val=fabs(val);
if(val<0.000001)return true;return false;
}
int main()
{
freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);tot=0;
for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
memset(gun,0,sizeof(gun));
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(x[i]==x[j])continue;
a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j]));
b=(y[i]-a*x[i]*x[i])/x[i];
if(a>=0.0)continue;
tot++;
for(int k=1;k<=n;k++)if(kill(k,a,b))gun[tot]|=(1<<(k-1));
}
for(int i=1;i<=n;i++)gun[++tot]|=(1<<(i-1));
sort(gun+1,gun+tot+1);
tot=unique(gun+1,gun+tot+1)-gun-1;
for(int i=1;i<=(1<<n);i++)f[i]=100000;f[0]=0;
for(int i=0;i<(1<<n);i++)
for(int j=1;j<=tot;j++)
f[i|gun[j]]=min(f[i]+1,f[i|gun[j]]);
cout<<f[(1<<n)-1]<<endl;
}
return 0;
}