P2519 [HAOI2011]problem a

Posted tidoblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2519 [HAOI2011]problem a相关的知识,希望对你有一定的参考价值。

题目描述

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

输入格式

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

输出格式

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

输入输出样例

输入 #1
3
2 0
0 2
2 2
输出 #1
1

说明/提示

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

 

这是一个非常神奇的问题

首先 有ai个人分数比i高 有bi个人分数比i低

那么很显然能够看出来

 ai+1  -   n-bi  这一段区间里的人的分数都是一样的

那么也就是说问题就转化为了

有许多的区间 这些个区间里的人的分数都是一样的

然后来看一看最多能保证这里面的多少区间是合法的

用n减去那个值就是至少有多少个人说的是假的

 

首先我们是要先把区间排一个序

然后要去重 这个去重就是如果有两个区间起点终点完全一样 那么就直接删掉一个 把另一个的权值+1

 

据说这就成了一个区间dp(听起来好像我没有学过的样子)

 

转移方程据说是这个样子的f[i]=minf[i-1],f[L-1]+V

这个是什么意思呢

可以是直接继承i-1 就是什么也不干

也可以用当前枚举到的右端点为i的区间  f[L-1]不就是到当前区间的左端点为止的最大收益吗  再加上当前区间的权值即可

 

其实我也是晕乎乎的  多做点题练一练就好啦

https://www.luogu.org/problem/P2519

/*
P2519 [HAOI2011]problem a
题目描述
一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)

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

输出格式
一个整数,表示最少有几个人说谎

输入输出样例
输入 #1复制
3
2 0
0 2
2 2
输出 #1复制
1
说明/提示
100%的数据满足: 1≤n≤100000 0≤ai、bi≤n

*/ /*
#include<bits/stdc++.h>
using namespace std;
struct node
    int l,r;//左端点 右端点 
 arr[100005];
int f[100005];
map<node,int> mp_node;//存储权值+判重 
bool cmp(node a,node b)
    if(a.r==b.r)return a.l<b.l;
    return a.r<b.r;

int main()

    int n;scanf("%d",&n);int n_arr=0;
    for(int i=1;i<=n;i++)
        int a,b;scanf("%d%d",&a,&b);
        int L=a+1,R=n-b;
        node tmp;tmp.l=L;tmp.r=R;
        if(!mp_node[tmp]) arr[++n_arr].l=L,arr[n_arr].r=R;
        mp_node[tmp]++; 
    
    sort(arr+1,arr+n_arr+1,cmp);
    int j=1;
    for(int i=1;i<=n;i++)
        f[i]=f[i-1];
        while(j<=n_arr&&arr[j].r==i)
            f[i]=max(f[i],f[arr[j].l-1]+mp_node[arr[j]]);
            j++;
        
    
    printf("%d",n-f[n]);
    return 0;
*/
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
struct node
    int l,r;
arr[maxn];
bool cmp(node a,node b)
    if(a.r==b.r) return a.l<b.l;
    return a.r<b.r;

int L[maxn],R[maxn],V[maxn],f[maxn];
int main()

    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)
        int x,y;scanf("%d%d",&x,&y);
        if(x+y>=n) continue;
        arr[i].l=x+1;arr[i].r=n-y;
    
    sort(arr+1,arr+n+1,cmp);
    int tot=0;
    for(int i=1;i<=n;i++)
        if(arr[i].l!=arr[i-1].l||arr[i].r!=arr[i-1].r) tot++;
        L[tot]=arr[i].l;R[tot]=arr[i].r; 
        V[tot]=min(V[tot]+1,arr[i].r-arr[i].l+1);//very important
    //    V[tot]++;
    
    int j=1;
    for(int i=1;i<=n;i++)
    
        f[i]=f[i-1];
        while(j<=tot&&R[j]==i)
            f[i]=max(f[i],f[L[j]-1]+V[j]);
            j++;
        
    
    printf("%d",n-f[n]);
    return 0;

 

以上是关于P2519 [HAOI2011]problem a的主要内容,如果未能解决你的问题,请参考以下文章

P2519 [HAOI2011]problem a

P2519 [HAOI2011]problem a

p2519 [HAOI2011]problem a

bzoj2301HAOI2011Problem b

BZOJ 2298: [HAOI2011]problem a

BZOJ 2301[HAOI2011]Problem b