UVALive 3695 Distant Galaxy (部分枚举,扫描维护)

http://acm.hust.edu.cn/vjudge/contest/131137#problem/C

题解:
这道题,还是大白书的。
确实没什么想法,想了很久也不知道该怎么写。
最暴力的就是直接枚举4个边界,然后统计一下。这样是O(n^5)的复杂度。
当然考虑优化:
我们仅仅枚举上下界,然后枚举右边界的时候可以顺便维护ans和M=on[j]-Left[j]。
当然,我是直接两重循环维护ans的,所以也不需要维护M。

#include
using namespace std;

const int maxn=105;
pair<int,int> P[maxn];

int Left[maxn],on[maxn],on2[maxn],Y[maxn];
int n;

int Solve() {
    int newL=unique(Y,Y+n)-Y;
    if(newL<=2)return n;
    int ans=0;
    for(int i=0; ifor(int j=i+1; jint yMin=Y[i],yMax=Y[j],num=0;
            for(int k=0; kif(k==0 || P[k].first^P[k-1].first) {
                    ++num;
                    on[num]=on2[num]=0;
                    Left[num]=(num==0?0:Left[num-1]+on2[num-1]-on[num-1]);
                }
                on[num]+=(P[k].second>yMin&&P[k].secondsecond>=yMin&&P[k].second<=yMax);
            }
            if(num<=2)return n;
            for(int k=1;k<=num;++k){
                for(int l=k+1;l<=num;++l){
                    ans=max(ans,Left[l]-Left[k]+on2[l]+on[k]);
                }
            }
        }
    }
    return ans;
}

int main() {
    int Tcase=0;
    while(~scanf("%d",&n),n) {
        for(int i=0; i"%d%d",&P[i].first,&P[i].second);
            Y[i]=P[i].second;
        }
        sort(P,P+n),sort(Y,Y+n);
        printf("Case %d: %d\n",++Tcase,Solve());
    }
    return 0;
}

你可能感兴趣的:(UVALive 3695 Distant Galaxy (部分枚举,扫描维护))