[noip2016]憤怒的小鳥 題解
阿新 • • 發佈:2019-02-17
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;
}