bzoj2298: [HAOI2011]problem a

题目链接

bzoj2298: [HAOI2011]problem a

题解

补集转化答案就是n - 最多人说真话
考虑每个人的话构成一段相等成绩区间
令同分数人的个数为区间权值,那么问题就是求最大权不相交区间

代码

/*************************************************************/
 
#include<map>
#include<vector>
#include<cstdio>
#include<cstring> 
#include<algorithm> 
inline int read() { 
    int x = 0,f = 1;
    char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}  
    while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
    return x * f;
}  
const int maxn = 100007; 
int n; 
struct node { 
    int l;int r,size; 
    node (int l = 0,int r = 0) : l(l) , r(r) {} ;  
    bool operator  < (const node a)const {
        if(l != a.l) return l < a.l; 
        return r < a.r;
    }
} ;
std::map <node,int> Seg;
std::vector<int>vec[maxn]; 
int dp[maxn]; 
int main() { 
    n = read(); 
    for(int a,b,i = 1;i <= n;++ i)  { 
        a = read() + 1,b = read(); 
        b = n - b; node Tmp;  
        if(Seg[Tmp = node(a,b)] < b - a + 1) Seg[Tmp] ++ ;
        if(Seg[Tmp] ==  1) vec[b].push_back(a); 
    } 
    int num = 0; 
    //std::sort(peo + 1,peo + n + 1);  
    for(int i = 1;i <= n;++  i) { 
        dp[i] = dp[i - 1]; 
        for(int j = 0;j < vec[i].size();++ j) {
            int l = vec[i][j]; 
            dp[i] = std::max(dp[i],dp[l - 1] + Seg[node(l,i)]); 
        }
    }
    printf("%d\n",n - dp[n]);   
    return 0; 
}
posted @ 2018-04-27 21:29  zzzzx  阅读(173)  评论(0编辑  收藏  举报