題目連接ios
平面內有n個點,每次能夠肯定一條過原點且開口向上的拋物線,將這條拋物線上全部的點都刪去。問最少須要刪幾回能夠刪掉所有的點。spa
n比較小,直接狀壓一下。由於已經肯定了要過原點。因此每兩個點均可以肯定一條拋物線。預處理出全部拋物線以及每條拋物線能夠刪掉的點。code
而後記憶化搜索,枚舉每次選擇的拋物線。轉移便可。get
注意精度!string
肯定拋物線的方法就用解二元一次方程組的方法便可。具體以下:io
設拋物線的二次項係數爲\(a\),一次項係數爲\(b\) ,兩個點的座標分別爲\((x_i,y_i),(x_j,y_j)\)。class
記\(k_1=x_i^2,k_2=x_i,k_3=y_i,k_4=x_j^2,k_5=x_j,k_6=y_j\)stream
而後就是解方程組搜索
\[\left\{ \begin{aligned} k_1a+k_2b=k_3& &(1)\\ k_4a+k_5b=k_6& &(2) \end{aligned} \right. \]queue
由\((1)\)得\(b=\frac{k_3-k_1a}{k_2}\),代回\((2)\)得\(a=\frac{k_2k_6-k_3k_5}{k_2k_4-k_1k_5}\)
#include<cstdio> #include<iostream> #include<cstdlib> #include<ctime> #include<cmath> #include<queue> #include<vector> #include<cstring> using namespace std; typedef long long ll; const double eps = 1e-9; ll read() { ll x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x * f; } int tot; bool calc(double a,double b,double x,double y) { return fabs(a * x * x + b * x - y) <= eps; } double x[20],y[20],a[400],b[400]; int sol[400]; int n,m,f[1 << 20]; int dfs(int now) { if(!now) return f[now] = 0; if(f[now] != -1) return f[now]; int ret = 100000; for(int i = 1;i <= tot;++i) { int t = now & sol[i]; if(t != now) ret = min(ret,dfs(t) + 1); } return f[now] = ret; } int main() { int T = read(); while(T--) { tot = 0; memset(f,-1,sizeof(f)); n = read(),m = read(); for(int i = 1;i <= n;++i) scanf("%lf%lf",&x[i],&y[i]); for(int i = 1;i <= n;++i) { for(int j = i + 1;j <= n;++j) { if(fabs(x[i] - x[j]) <= eps) continue; ++tot; double k1 = x[i] * x[i],k2 = x[i],k3 = y[i],k4 = x[j] * x[j],k5 = x[j],k6 = y[j]; a[tot] = ((k6 * k2 - k3 * k5)) / ((k4 * k2 - k1 * k5)); b[tot] = (k3 - k1 * a[tot]) / k2; if(a[tot] >= 0) --tot; } } for(int i = 1;i <= tot;++i) { sol[i] = (1 << n) - 1; for(int j = 1;j <= n;++j) if(calc(a[i],b[i],x[j],y[j])) sol[i] ^= (1 << (j - 1)); } for(int i = 1;i <= n;++i) { ++tot; sol[tot] = ((1 << n) - 1) ^ (1 << (i - 1)); } printf("%d\n",dfs((1 << n) - 1)); } return 0; }