zoukankan      html  css  js  c++  java
  • [区间dp][二分] Bzoj P2298 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

    题解

    • 题目要我们求有多少个说假话的,可以改成最多有多少个说真话的
    • 有a个人比我分数高,有b个人比我分数低,那么其实可以转换为一个区间[a+1,n-b]
    • 那么可以发现,有交集的两个区间里必定有一个是假的
    • 这样问题就转化为了给了n个区间,求最多不相交的区间数
    • 首先,可以先排除掉a+1>n-b的
    • 还要将相同区间的合并,而且不能超过可合并的个数(也就是r-l+1)
    • 最后就是dp了,设f[i]为前i个区间中不相交的最多区间数
    • 考虑转移:
    • ①f[i]=f[i-1],也就是当前区间不用了
    • ②可以在前面以右端点排过序的区间里,二分一个相邻最近的区间的f[x]加上e[i].d(也就是这个区间合并了多少个区间数)

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 const int inf=1e9+7;
     7 struct edge { int l,r,d; }e[100010];
     8 int k,f[100010],n,m;
     9 bool cmp(edge a,edge b) { return a.r==b.r?a.l<b.l:a.r<b.r; }
    10 int find(int x)
    11 {
    12     int l=1,r=x-1,mx=0;
    13     while (l<=r)
    14     {
    15         int mid=(l+r)/2;
    16         if (e[mid].r<e[x].l) mx=mid,l=mid+1; else r=mid-1;
    17     }
    18     return f[mx];
    19 }
    20 int main()
    21 {
    22     scanf("%d",&n); m=n;
    23     for (int i=1;i<=n;i++)
    24     {
    25         int x,y;
    26         scanf("%d%d",&x,&y);
    27         e[i].l=x+1; e[i].r=n-y; e[i].d=1;
    28         if (e[i].r<e[i].l) e[i].r=inf;
    29     }
    30     sort(e+1,e+n+1,cmp);
    31     k=1;
    32     for (int i=2;i<=n;i++)
    33         if (e[i].l==e[k].l&&e[i].r==e[k].r&&e[i].d+e[k].d<=e[k].r-e[k].l+1)    e[k].d+=e[i].d,e[i].r=inf;
    34         else k=i;
    35     sort(e+1,e+n+1,cmp);
    36     for (int i=1;i<=n;i++) if (e[i].r==inf) n=i-1;
    37     for (int i=1;i<=n;i++) f[i]=max(f[i-1],find(i)+e[i].d);
    38     printf("%d",m-f[n]);
    39     return 0;
    40 }
  • 相关阅读:
    创业公司技术总监,去上市公司面试,结果凉了!
    Java开发最常犯的10个错误,打死都不要犯!
    这 17 个 JVM 参数,高级 Java 必须掌握!
    推荐几个顶级的IT技术公众号,坐稳了!
    Spring Boot 面试,一个问题就干趴下了!(下)
    密码已进入"淘汰"倒计时!
    一条简单的 SQL 执行超过1000ms,纳尼?
    天天用Synchronized,底层原理是个啥?
    为什么很多程序员工作时都戴耳机?
    Java转型大数据开发全套教程,都在这儿!
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9439125.html
Copyright © 2011-2022 走看看