• P2831 [NOIP2016 提高组] 愤怒的小鸟


    Problem

    平面上有(n)个在第一象限的点,求至少要用几个类似于(y = ax^2 + bx(a < 0,a,b in mathbb{R}))的抛物线能将其全部覆盖。
    (n le 18)

    Solution

    Thinking 1

    (1 le n le 18),状压dp.
    (dp[S])为S状态下至少要用几个抛物线。

    Thinking 2

    发现抛物线必经((0,0))。所以再选两点即可确定抛物线。
    具体来说:现在有两个点((x_1,y_1),(x_2,y_2)),那么得:

    [egin{cases} ax_1^2 + bx_1 = y_1\ ax_2^2 + bx_2 = y_2\ end{cases} ]

    1式乘上(x_2),2式乘上(x_1),得

    [ax_1^2x_2 + bx_1x_2 = y_1x_2\ ax_2^2x_1 + bx_1x_2 = y_2x_1 ]

    相减

    [a(x_1^2x_2 - x_2^2x_1) = y_1x_2 - y_2x_1\ a = dfrac{y_1x_2 - y_2x_1}{x_1^2x_2 - x_2^2x_1} ]

    (b)同理吧。

    Thinking 3

    考虑如何求(dp[S])

    • (dp[S])的个数<2,则$dp[S] = $个数。
    • otherwise,(dp[S] = min{dp[S - s]} + 1)
      其中(s)是指:
      (S)中选两点((x_i,y_i),(x_j,y_j))
      首先判断其确定的表达式中的(a)是否小于0
      然后求出(k),满足(i eq j eq k)((x_k,y_k))在这个抛物线,(s)加上(2^{k - 1})
      注意s要加入i,j
      做完了。

    Thinking 4

    其实我感觉用那个三点式和三分瞎搞搞也是能做的。

    # include <bits/stdc++.h>
    using namespace std;
    # define int long long
    const int N = 22;
    const double eps = 1e-8;
    int T,n,m;
    struct node 
    {
        double x,y; 
        node() {}
        node(double _x,double _y) : x(_x),y(_y) {}
    }a[N];
    int dp[(1 << 20) + 5];
    
    double f(double x,double x1,double x2,double x3,double y1,double y2,double y3)
    {
        return (((x - x2) * (x - x3)) / ((x1 - x2) * (x1 - x3))) * y1 + (((x - x1) * (x - x3)) / ((x2 - x1) * (x2 - x3))) * y2 + (((x - x1) * (x - x2)) / ((x3 - x1) * (x3 - x2))) * y3;
    }
    
    void equ(double &a,double &b,double x1,double x2,double y1,double y2)
    {
        a = -((y1 * x2 - y2 * x1) / (x2 * x2 * x1 - x1 * x1 * x2));
        b = ((y1 * x2 * x2) - (y2 * x1 * x1)) / (x1 * x2 * x2 - x1 * x1 * x2);
        return;
    }
    
    signed main(void)
    {
        // freopen("2831.in","r",stdin);
        // freopen("2831.out","w",stdout);
        scanf("%lld",&T);
        while(T--)
        {
            scanf("%lld%lld",&n,&m);
            for(int i = 1; i <= n; i++) 
            {
                scanf("%lf%lf",&a[i].x,&a[i].y);
            }
            for(int i = 0; i < (1 << n); i++)
            {
                dp[i] = 0;
                for(int j = 1; j <= n; j++)
                {
                    if(i >> (j - 1) & 1) 
                    {
                        ++dp[i];
                    }
                }
                // printf("dp[%lld] = %lld
    ",i,dp[i]);
            }
            for(int S = 0; S < (1 << n); S++)
            {
                int s = 0;
                for(int i = 1; i <= n; i++)
                {
                    for(int j = i + 1; j <= n; j++)
                    {
                        if(!((S >> (i - 1) & 1) && (S >> (j - 1) & 1))) continue; 
                        if(fabs(a[i].x - a[j].x) < eps) continue;
                        double A,B;
                        equ(A,B,a[i].x,a[j].x,a[i].y,a[j].y);
                        if(A > -eps) continue;
                        s = (1 << (i - 1)) + (1 << (j - 1));
                        for(int k = 1; k <= n; k++)
                        {
                            if(k == i || k == j) continue;
                            if(fabs(A * a[k].x * a[k].x + B * a[k].x - a[k].y) < eps) 
                            {
                            // printf("i = %lld,j = %lld, k = %lld
    ",i,j,k);
                                s = (s + (1 << (k - 1)));
                            }
                        }
                        if(S - s >= 0) dp[S] = min(dp[S],dp[S - s] + 1);
                        
                    }
                }
            }
            printf("%lld
    ",dp[(1 << n) - 1]);
        }
        return 0;
    }
    
  • 相关阅读:
    Python使用SMTP模块、email模块发送邮件
    harbor搭建及使用
    ELK搭建-windows
    ELK技术栈之-Logstash详解
    【leetcode】1078. Occurrences After Bigram
    【leetcode】1073. Adding Two Negabinary Numbers
    【leetcode】1071. Greatest Common Divisor of Strings
    【leetcode】449. Serialize and Deserialize BST
    【leetcode】1039. Minimum Score Triangulation of Polygon
    【leetcode】486. Predict the Winner
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/15122780.html
Copyright © 2020-2023  润新知