码迷,mamicode.com
首页 > 其他好文 > 详细

【题解】SCOI2007组队

时间:2018-11-05 14:00:21      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:\n   ==   操作   using   read   最小值   内容   复杂度   min   

  恩……为什么大家都这么执着于 \(O(n^{2})\) 的复杂度捏?如果接受 \(O(nV)\) 的复杂度,那这题可不是道**题吗( • ?ω•? )?

  首先把所有的人按照身高排个序,然后我们就可以枚举一个人作为身高的最小值。此时,原式

\(A * H + B * V - C <= A * minh + B * minv\) 

我们可以把常量固定一下:

\(S_{x} = A * H_{x} - C - A * minh\)

\(S_{x} + B * V_{x} <= B * minv\)

移项得到 \(V_{x} - minv <= -S_{x}\)

不过仅仅满足这一个条件还不够,还有一个限制条件为

\(V_{x} >= minv\)

整理一下,把 minv 作为变量

 \( S_{x} + V_{x} <= minv <= V_{x}\)

 这样我们在 v 的取值范围上差分一下,取最值即可。

  以及虽然复杂度略高,但是鉴于优秀的常数 & 算法内容的操作简单,跑起来很快 :洛谷rank1~

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
int n, A, B, C, mx, ans, a[maxn]; 

int read()
{
    int x = 0, k = 1;
    char c; c = getchar();
    while(c < 0 || c > 9) { if(c == -) k = -1; c = getchar(); }
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar();
    return x * k;
}

struct node
{
    int v, h;
    friend bool operator <(const node& a, const node& b)
    { return a.h < b.h; }
}P[maxn];

void Work(int x)
{
    int H = P[x].h, T = H * A;
    for(int i = x; i <= n; i ++) 
    {
        int l = max(0, P[i].v - (T - A * P[i].h + C) / B);
        int r = P[i].v;
        if(l > r) continue;
        a[l] ++, a[r + 1] --;
    }
    
    for(int i = 0, tem = 0; i <= mx; i ++) 
    {
        a[i] += tem; tem = a[i];
        ans = max(ans, a[i]); a[i] = 0;
    }
}

int main()
{
    n = read(); A = read(), B = read(), C = read();
    for(int i = 1; i <= n; i ++) 
    {
        P[i].h = read(), P[i].v = read();
        mx = max(mx, P[i].v);
    }
    sort(P + 1, P + 1 + n);
    for(int i = n; i >= 1; i --) Work(i);
    printf("%d\n", ans);
    return 0;
}

 

【题解】SCOI2007组队

标签:\n   ==   操作   using   read   最小值   内容   复杂度   min   

原文地址:https://www.cnblogs.com/twilight-sx/p/9908713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!