zoukankan      html  css  js  c++  java
  • bzoj2298 [HAOI2011]problem a

    Description

    一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)

    Input

    第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、bi

    Output

    一个整数,表示最少有几个人说谎

    每个人的表述等价于排名[ai+1,n-bi]的人分数相同且区间外的人分数不同

    将相同的区间合并并记录个数作为权值,若个数超过区间长度则以区间长度为准

    于是问题转化为取一些互不相交的区间使权值和最大,可以dp解决,用树状数组优化可做到O(nlogn)

    #include<cstdio>
    #include<algorithm>
    struct seg{
        int l,r,t;
    }ss[100005];
    inline bool operator<(const seg&a,const seg&b){
        return a.r!=b.r?a.r<b.r:a.l<b.l;
    }
    int n,p=0;
    int bit[100005];
    inline void maxs(int&a,int b){if(a<b)a=b;}
    inline void ins(int w,int x){
        ++w;
        while(w<=n+1)maxs(bit[w],x),w+=w&-w;
    }
    inline int find(int w){
        ++w;
        int ans=0;
        while(w)maxs(ans,bit[w]),w-=w&-w;
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=0,l,r;i<n;i++){
            scanf("%d%d",&l,&r);
            ++l;r=n-r;
            if(l<=r)ss[p++]=(seg){l,r,1};
        }
        std::sort(ss,ss+p);
        int p2=0;
        for(int i=1;i<p;i++){
            if(ss[i].l==ss[p2].l&&ss[i].r==ss[p2].r)++ss[p2].t;
            else ss[++p2]=ss[i];
        }
        p=p2+1;
        for(int i=0;i<p;i++){
            int c=ss[i].r-ss[i].l+1;
            if(ss[i].t>c)ss[i].t=c;
        }
        int ans=0;
        for(int i=0;i<p;i++){
            int c=ss[i].t+find(ss[i].l-1);
            maxs(ans,c);
            ins(ss[i].r,c);
        }
        printf("%d
    ",n-ans);
        return 0;
    }
  • 相关阅读:
    win7为IIS7添加程序映射
    【整理】在一亿个数中寻找出现频率最多的4个 <转>
    优化SQL Server数据库的几个大招<转>
    最长单调子序列(DP)
    详细解说 STL 排序
    获取word中的原始大小图片
    MD5 算法实现(c++)
    udp 通信中的端口问题
    Yacc 与 Lex 快速入门
    HDOJ (HDU) 1561 The more, The Better (树形DP)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5493803.html
Copyright © 2011-2022 走看看