题解 P2831 【愤怒的小鸟】

题目链接

Solution 愤怒的小鸟

题目大意:第一象限内有\(n\)个点(\(n \leq 18\)),求最少要多少条形如\(y=ax^2+bx \quad a<0,a,b, \in R\) 的抛物线才能覆盖所有点

状压\(dp\)


分析:\(n\)的数据范围很小,因此我们可以考虑状压\(dp\),填表法不好做我们可以用刷表法

\(f[S]\)表示覆盖集合\(S\)内点的最小代价

显然\(f[0]= 0\)

\(f[S|line[i][j]] = min\{f[S] + 1\}\)其中\(line[i][j]\)表示经过\(i,j\)两点的抛物线可以覆盖的点的集合

\(f[S | 1<

这样单次复杂度\(O(2^nn^2)\),有点悬

状态的\(2^n\)不能消掉我们从转移入手

原来每次枚举所有没有被覆盖的点是\(n^2\)的,我们固定其中一个点为没有被覆盖的点中编号最小的,这样转移就是\(n\)

为什么这样是对的?因为我们最终要求的是覆盖所有的点,当前状态不覆盖最小的点也会被下一个状态覆盖,所以可以直接钦定一个点

这题样例都卡精度,醉了

#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 23;
typedef long double type;
const type eps = 1e-7;
struct Pos{
    type x,y;
}val[maxn];
int t,n,m,dp[1 << maxn],lowbit[1 << maxn],line[maxn][maxn];//lowbit表示最小的为0的点的编号
inline bool cmp(type a,type b){return abs(a - b) < eps;}
void gauss(type &x,type &y,type a1,type b1,type c1,type a2,type b2,type c2){
    x = (c1 * b2 - c2 * b1) / (a1 * b2 - a2 * b1);
    y = (c1 - a1 * x) / b1;
}
inline void solve(){
    cin >> n >> m;
    for(int i = 0;i < n;i++)
        cin >> val[i].x >> val[i].y;
    memset(line,0,sizeof(line));
    memset(dp,0x3f,sizeof(dp));
    dp[0] = 0;
    for(int i = 0;i < n;i++)
        for(int j = 0;j < n;j++){
            if(cmp(val[i].x,val[j].x))continue;
            type a,b;
            gauss(a,b,val[i].x * val[i].x,val[i].x,val[i].y,val[j].x * val[j].x,val[j].x,val[j].y);
            if(a > -eps)continue;
            for(int k = 0;k < n;k++)
                if(cmp(a * val[k].x * val[k].x + b * val[k].x,val[k].y))line[i][j] |= 1 << k;
        }
    for(int i = 0;i < 1 << n;i++){
        int j = lowbit[i];
        dp[i | (1 << j)] = min(dp[i | (1 << j)],dp[i] + 1);
        for(int k = 0;k < n;k++)
            dp[i | line[j][k]] = min(dp[i | line[j][k]],dp[i] + 1);
    }
    cout << dp[(1 << n) - 1] << '\n';
}
int main(){
    for(int i = 0;i < (1 << 18);i++){
        int j = 0;
        for(;(i >> j) & 1;j++);
        lowbit[i] = j;
    }
    cin >> t;
    while(t--)solve();
    return 0;
}

你可能感兴趣的:(题解 P2831 【愤怒的小鸟】)