BZOJ1071 [SCOI2007]组队

说好的一天一题解来啦~(其实是给马上要来的NOIP模拟赛加点RP>.<)

Vfk大神说是n^2乱搞,于是蒟蒻就开始乱搞,结果发现怎么搞都是O(n ^ 3)的。。。

后来请教了snake大神,他说先给sum = A * h + B * s排序,然后枚举h和s的最小值。(h -- Height, s -- Speed)

然后就是两个指针乱搞:

先枚举s最小值,然后一边枚举v的最小值一边查询符合条件的人数,因为这一定是相邻的一串。

 1 /**************************************************************
 2     Problem: 1071
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:1708 ms
 7     Memory:1044 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12  
13 using namespace std;
14  
15 struct data{
16     int s, h, sum;
17 }x[10000], y[10000];
18  
19 inline bool cmp1(const data &a, const data &b){
20     return a.h < b.h;
21 }
22  
23 inline bool cmp2(const data &a, const data &b){
24     return a.sum < b.sum;
25 }
26  
27 int n, Max, Min, l, r, cnt, ans;
28 int A, B, C;
29  
30 inline bool check1(int p){
31     return y[p].s <= Max && y[p].s >= Min;
32 }
33  
34 inline bool check2(int p){
35     return x[p].s <= Max && x[p].s >= Min;
36 }
37  
38 int main(){
39     scanf("%d", &n);
40     scanf("%d%d%d", &A, &B, &C);
41     for (int i = 1; i <= n; ++i){
42         scanf("%d%d", &x[i].h, &x[i].s);    
43         x[i].sum = A * x[i].h + B * x[i].s;
44         y[i] = x[i];
45     }
46      
47     sort(x + 1, x + n + 1, cmp1);
48     sort(y + 1, y + n + 1, cmp2);
49     for (int i = 1; i <= n; ++i){
50         Min = x[i].s, Max = Min + C / B;
51         l = 0, r = 0, cnt = 0;
52         for (int j = 1; j <= n; ++j){
53             while (r < n && y[r + 1].sum <= A * x[j].h + B * x[i].s + C)
54                 ++r, cnt += check1(r);
55             while (l < n && x[l + 1].h < x[j].h)
56                 ++l, cnt -= check2(l);
57             ans = max(ans, cnt);    
58         }
59     }
60     printf("%d
", ans);
61     return 0;
62 }
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4007292.html