cogs 999. [東方S2]雾雨魔理沙

二次联通门 : cogs 999. [東方S2]雾雨魔理沙

 

 

 

摸你傻赛高!!

 

/*
    cogs 999. [東方S2]雾雨魔理沙
    
    原来以为是一道计算几何的题
    
    可是细细一想发现。。
    这就是一道dp
    
    由于给定了斜率
    每个点的b值也可以确定了(y = kx + b)
    
    按照b值排序
    后区间dp搞搞就好了 

*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

#define PI 3.1415926

void read (int &now)
{
    register char word = getchar ();
    int temp = 0;
    for (now = 0; !isdigit (word); word = getchar ())
        if (word == '-')
            temp = 1;
    for (; isdigit (word); now = now * 10 + word - '0', word = getchar ());
    if (temp)
        now = -now;
}

double k;

struct Point
{
    int x, y;
    
    int value, mul;
    
    Point (int __x, int __y, int __v, int __m) : x (__x), y (__y), value (__v), mul (__m){}
    Point () {}

    bool operator < (const Point &now) const
    {
        return (this->y - (this->x * k)) < (now.y - (now.x * k));
    }
};

#define Max 2008
Point point[Max];

int _sum[Max], _mul[Max];
double dp[Max];

inline double max (double a, double b)
{
    return a > b ? a : b;
}

#define Cogs

int main (int argc, char *argv[])
{
#ifdef Cogs

    freopen ("marisa.in", "r", stdin);
    freopen ("marisa.out", "w", stdout);

#endif
    
    int N;
    read (N);
    register int i, j;
    
    for (i = 1; i <= N; ++ i)
        read (point[i].x), read (point[i].y), read (point[i].value), read (point[i].mul);
    
    scanf ("%lf", &k);
    k = tan (k / 360 * 2 * PI);
    
    std :: sort (point + 1, point + 1 + N);
    
    for (i = 1; i <= N; ++ i)
    {
        _sum[i] = _sum[i - 1] + point[i].value;
        _mul[i] = _mul[i - 1] + point[i].mul;
        
        dp[i] = 0;

        for (j = 1; j <= i; ++ j)
            dp[i] = max (dp[i], dp[j - 1] + double(_sum[i] - _sum[j - 1]) * (_mul[i] - _mul[j - 1]) / (i - j + 1));
    }
    
    
    printf ("%.3lf", dp[N]);
    
    return 0;
}

 

posted @ 2017-08-09 15:43  ZlycerQan  阅读(230)  评论(0编辑  收藏  举报