「NOIP2016」 憤怒的小鳥【狀態壓縮】
阿新 • • 發佈:2018-12-11
表示選擇第和兩隻小鳥得到的值可以打中哪些小鳥。
然後直接注意精度轉移一下就可以了吖:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define db double #define rep(i,x,y) for(int i=(x);i<=(y);i++) #define repl(i,x,y) for(int i=(x);i<(y);i++) #define repd(i,x,y) for(int i=(x);i>=(y);i--) using namespace std; const int N=20; const int Inf=1e9; const db eps=1e-10; int t,n,m,f[1<<N],par[N][N]; struct node { db x,y; }bird[N]; void init() { scanf("%d%d",&n,&m);m=(1<<n)-1; rep(i,1,n) scanf("%lf%lf",&bird[i].x,&bird[i].y); rep(i,1,n) rep(j,i+1,n) { par[i][j]=0; if(fabs(bird[i].x-bird[j].x)<eps) continue; db x1=bird[i].x; db y1=bird[i].y; db x2=bird[j].x; db y2=bird[j].y; db b=(y1*x2*x2-y2*x1*x1)/(x1*x2*(x2-x1)); db a=(y1-b*x1)/(x1*x1); if(a<-eps) rep(k,1,n) { db x=bird[k].x,y=bird[k].y; if(fabs(a*x*x+b*x-y)<=eps) par[i][j]|=(1<<(k-1)); } } } void solve() { rep(i,1,m) f[i]=Inf;f[0]=0; rep(s,0,m) if(f[s]!=Inf) { rep(i,1,n) { rep(j,i+1,n) f[s|par[i][j]]=min(f[s|par[i][j]],f[s]+1); f[s|(1<<(i-1))]=min(f[s|(1<<(i-1))],f[s]+1); } } printf("%d\n",f[m]); } int main() { scanf("%d",&t); while(t--) { init(); solve(); } return 0; }