题解SCOI2007组队
Posted twilight-sx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解SCOI2007组队相关的知识,希望对你有一定的参考价值。
恩……为什么大家都这么执着于 (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 ", ans); return 0; }
以上是关于题解SCOI2007组队的主要内容,如果未能解决你的问题,请参考以下文章