P2831 Angry Birds
We first preprocess each pig between 22 (set to $u,v$) and the origin of the three-point determination of the parabola (when the two pig horizontal axis is equal, obviously no solution)
The number of points that the parabolic $u,v$ determines can be processed, recorded as $lines[u][v]$
Set $f[i]$ to indicate that the set of pigs that have been wiped is the minimum parabolic number required when the binary is represented as $i$
Apparently $f[0]=0$
$f [I| ( 1<< (u-1))]=min (f[i| ( 1<< (u-1)],f[i]+1) $ (a parabola only strings one point)
$f [I|lines[u][v]]=min (f[i|lines[u][v]],f[i]+1) $
Then goose this is $o (Tn^{2}2^{n}) $,CCF's Royal chance T
So we're thinking about optimizing
We find that when we add a parabola, there is no difference between the first string $1,4$ and the first string $2,3$, but both of us enumerate them in different order.
Then we can work out the $mex$ of the set $i$ (the smallest positive integer that does not appear in the collection)
Add restrictions when enumerating: Be sure to include $mex[i]$
The enumeration then drops from $o (n^{2}) $ to $o (n) $
Total complexity dropped to $o (Tn2^{n}) $
End.
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>#defineRe Registerusing namespaceStd;typedefDoubledb;intMinint&a,int&B) {returnA<b?a:b;}#defineN 524589ConstDB eps=1e-8;d b x[ -],y[ -];intt,n,m,lines[ -][ -],f[n],mex[n];voidCalc (db &a,db &b,db x1,db y1,db x2,db y2) {b= (x1*x1*y2-x2*x2*y1)/(x1*x1*x2-x1*x2*x2); A= (y1-x1*b)/(x1*x1);} For solving a two-second equation setintMain () { for(ReintI=0,j;i<262144;++i) {//Pretreatment Mex for(j=0;(i& (1<<J)) &&j< -;++j); Mex[i]=J; }SCANF ("%d",&t); while(t--) {scanf ("%d%d",&n,&m); DB A, B; for(ReintI=1; i<=n;++i) scanf ("%LF%LF",&x[i],&Y[i]); for(ReintI=1; i<=n;++i) for(Reintj=1; j<=n;++j) {Lines[i][j]=0; if(Fabs (X[i]-x[j]) <eps)Continue;//horizontal axis equal without solution calc (a,b,x[i],y[i],x[j],y[j]); if(a>-eps)Continue; for(Reintu=1; u<=n;++u)if(Fabs (A*x[u]*x[u]+b*x[u]-y[u]) <EPS) lines[i][j]|=(1<< (U1) ;//Find all the points where this parabola can be connected} memset (F, the,sizeof(f)); f[0]=0; for(ReintI=0,j=mex[i];i< (1<<N); j=mex[++i]) {F[i| (1<<J)]=min (f[i| (1<<J)],f[i]+1); A single point with one piece of the case for(Reintu=1; u<=n;++u)//The parabola of the enumeration must pass through J F[i|lines[j+1][u]]=min (f[i|lines[j+1][u]],f[i]+1); } printf ("%d\n", f[(1<<n)-1]); }return 0;}
P2831 Angry Birds (like pressure dp)