1. 程式人生 > >【題解】SCOI2007組隊

【題解】SCOI2007組隊

mes 最小 using bsp har 接受 max sco read

  恩……為什麽大家都這麽執著於 \(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組隊