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

    (color{#0066ff}{ 题目描述 })

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

    $color{#0066ff}{ 输入格式 } $

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

    (color{#0066ff}{输出格式})

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

    (color{#0066ff}{输入样例})

    3
    2 0
    0 2
    2 2
    

    (color{#0066ff}{输出样例})

    1
    

    (color{#0066ff}{数据范围与提示})

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

    (color{#0066ff}{ 题解 })

    把问题转换一下

    考虑最后的排名,假设我们按成绩从大到小排

    那么可以发现,每个人的条件变成了([a_i+1,n-b_i])的人成绩一样

    然后就转化为了区间问题。。。

    首先,那些区间r<l的。。显然是假话

    然后可以发现,任何两个区间一旦非重合相交,就有人说假话,不合法

    于是我们把l和r都相同的人合并,记区间权值为等于这个区间的人的个数

    于是问题变为,选出尽量多不相交,权值尽量大

    序列DP。

    (f[i])表示进行到i位置的最大值,把区间排个序,维护一个单调指针转移即可

    注意答案一部分是n-f,一部分是不合法的人!

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int maxn = 1e5 + 100;
    struct node {
    	int l, r, num;
    }a[maxn]; 
    int n, f[maxn];
    bool cmp1(const node &a, const node &b) {
    	return (a.l < b.l || (a.l == b.l && a.r < b.r));
    }
    bool cmp2(const node &a, const node &b) {
    	return a.r < b.r;
    }
    int main() {
    	int _  = in();
    	for(int i = 1; i <= _; i++) {
    		a[i].l = in() + 1, a[i].r = _ - in();
    		if(a[i].l <= a[i].r) a[++n] = a[i];
    		a[n].num = 1;
    	}
    	std::sort(a + 1, a + n + 1, cmp1);
    	int tot = 1;
    	for(int i = 2; i <= n; i++) {
    		if(a[i].l == a[i - 1].l && a[i].r == a[i - 1].r) a[tot].num++;
    		else a[++tot] = a[i];
    	}
    	int now = 1;
    	std::sort(a + 1, a + tot + 1, cmp2);
    	for(int i = 1; i <= tot; i++) a[i].num = std::min(a[i].num, a[i].r - a[i].l + 1);
    	for(int i = 1; i <= _; i++) {
    		f[i] = f[i - 1];
    		while(now <= tot && a[now].r == i) {
    			f[i] = std::max(f[i], f[a[now].l - 1] + a[now].num);
    			now++;
    		}
    	} 
    	printf("%d
    ", _ - f[_]);
    	return 0;
    }
    
  • 相关阅读:
    c# 泛型总结
    透过字节码分析java基本类型数组的内存分配方式。
    c#索引器
    redis在asp.net 中的应用
    Unity3D shaderLab
    Unity3d Asset Store 打不开
    C# 类型转换的开销
    [转]权重算法
    Coroutine的原理以及实现
    在Unity3D里使用WinForm
  • 原文地址:https://www.cnblogs.com/olinr/p/10343945.html
Copyright © 2011-2022 走看看