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

    Description

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

    Input

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

    Output

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

    Sample Input

    3

    2 0

    0 2

    2 2

    Sample Output

    1

    HINT

    100%的数据满足: 1≤n≤100000   0≤ai、bi≤n

    正解:$dp$+树状数组优化。

    对于每一个人,我们可以求出他的分数表示的排名范围:$[1+a,n-b]$。

    那么我们可以把最少说慌的人转化成最多说实话的人,如果两个人的区间相交且不重合,那么他们两人必定有一人说谎。如果相同区间的人数超过了区间长度,那么多于区间长度的那些人必定说谎了,也直接去掉就行了。

    把重合的区间合并起来,那么我们的问题变成了求带权的最大不相交区间数,这是一个经典的$dp$,可以用树状数组优化。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define N (100010)
    14 #define il inline
    15 #define RG register
    16 #define ll long long
    17 #define lb(x) (x & -x)
    18 
    19 using namespace std;
    20 
    21 struct data{ int l,r,v; }q[N],s[N];
    22 
    23 int f[N],c[N],n,cnt,ans;
    24 
    25 il int gi(){
    26   RG int x=0,q=1; RG char ch=getchar();
    27   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    28   if (ch=='-') q=-1,ch=getchar();
    29   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    30   return q*x;
    31 }
    32 
    33 il int cmp(const data &a,const data &b){
    34   if (a.l==b.l) return a.r<b.r; return a.l<b.l;
    35 }
    36 
    37 il int cmpr(const data &a,const data &b){ return a.r<b.r; }
    38 
    39 il void update(RG int x,RG int v){
    40   for (;x<=n;x+=lb(x)) c[x]=max(c[x],v); return;
    41 }
    42 
    43 il int query(RG int x){
    44   RG int res=0; for (;x;x-=lb(x)) res=max(res,c[x]); return res;
    45 }
    46 
    47 int main(){
    48 #ifndef ONLINE_JUDGE
    49   freopen("a.in","r",stdin);
    50   freopen("a.out","w",stdout);
    51 #endif
    52   n=gi();
    53   for (RG int i=1,a,b;i<=n;++i) a=gi(),b=gi(),q[i]=(data){1+a,n-b};
    54   sort(q+1,q+n+1,cmp),q[n+1].l=-1;
    55   for (RG int i=1,res=1;i<=n;++i){
    56     if (q[i].l>q[i].r || q[i].l<0 || q[i].r>n){ res=1; continue; }
    57     if (q[i].l!=q[i+1].l || q[i].r!=q[i+1].r)
    58       s[++cnt]=(data){q[i].l,q[i].r,min(q[i].r-q[i].l+1,res)},res=1; else ++res;
    59   }
    60   sort(s+1,s+cnt+1,cmpr);
    61   for (RG int i=1;i<=cnt;++i)
    62     f[s[i].r]=max(f[s[i].r],s[i].v+query(s[i].l-1)),update(s[i].r,f[s[i].r]),ans=max(ans,f[s[i].r]);
    63   printf("%d
    ",n-ans); return 0;
    64 }
  • 相关阅读:
    减少.NET应用程序内存占用的一则实践
    ASP.NET中检测图片真实否防范病毒上传
    PHP、Python 相关正则函数实例
    利用脚本将java回归到面向函数式编程
    ASP.Net 实现伪静态方法及意义
    ExecuteNonQuery()方法
    在.net中使用split方法!
    str.split()如何用?谢谢
    输出货币型
    (DataRowView)e.Item.DataItem只有在ItemDataBound这个事件中起效
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7351885.html
Copyright © 2011-2022 走看看