zoukankan      html  css  js  c++  java
  • [HAOI 2011] Problem A

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=2298

    [算法]

             考虑用总人数 - 最多人说真话

             显然 , 对于每个人 , 如果他说的是真话 , 那么他的排名必然在[ai + 1 , n - bi]中 , 否则不合法

             统计出每个合法区间相同的个数

             那么问题转化为了 :

             现在有一些线段 , 每条线段[li , ri]有一个权值wi , 从中选取若干条使得权值和最大

             考虑dp 

             将区间按右端点排序 , 用fi表示前i个区间的最大权值和 , 通过二分求出最大的pos使得rpos < li

             有转移方程fi = max{fi-1 , fpos + w}

             答案即为n - fn

             时间复杂度 : O(NlogN)

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    struct segment
    {
            int l , r;
    } s[N];
    struct info
    {
            int l , r;
            int value;
    } e[N];
    
    int n , m , tot;
    int a[N] , b[N] , dp[N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool cmpa(segment a , segment b)
    {
            if (a.l != b.l) return a.l < b.l;
            else return a.r < b.r;
    }
    inline bool cmpb(info a , info b)
    {
            return a.r < b.r;        
    }
    
    int main()
    {
            
            read(n);
            for (int i = 1; i <= n; ++i)
            {
                    read(a[i]);
                    read(b[i]);
                    if (a[i] + 1 <= n - b[i])    
                            s[++tot] = (segment){a[i] + 1 , n - b[i]};    
            }
            sort(s + 1 , s + tot + 1 , cmpa);
            for (int i = 1; i <= tot; ++i)
            {
                    if (s[i].l == s[i - 1].l && s[i].r == s[i - 1].r)    
                    {
                            if (e[m].value != s[i].r - s[i].l + 1) 
                                    ++e[m].value;
                            continue;
                    } else
                            e[++m] = (info){s[i].l , s[i].r , 1}; 
            }
            sort(e + 1 , e + m + 1 , cmpb);
            for (int i = 1; i <= m; ++i)
            {
                    int l = 1 , r = i , k = 0;
                    while (l <= r)
                    {
                            int mid = (l + r) >> 1;
                            if (e[mid].r < e[i].l)
                            {
                                    k = mid;
                                    l = mid + 1;
                            } else r = mid - 1;
                    }        
                    dp[i] = max(dp[i - 1] , dp[k] + e[i].value);
            }
            printf("%d
    " , n - dp[m]);
            
            return 0;
        
    }
  • 相关阅读:
    Flask 服务器设置host=0.0.0.0之后外部仍然无法访问
    HTB::Sauna
    VulnHub::DC-4
    【CTFHub 技能树】RCE
    【CTFHub 技能树】反射型XSS
    VulnHub::DC-3
    HashMap中add()方法的源码学习
    equals和HashCode深入理解(转)
    AQS原理分析
    初步认识线程安全性
  • 原文地址:https://www.cnblogs.com/evenbao/p/10623853.html
Copyright © 2011-2022 走看看