码迷,mamicode.com
首页 > 其他好文 > 详细

P2519 [HAOI2011]problem a

时间:2019-09-08 22:19:59      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:ref   一段   min   ace   tin   print   form   https   ||   

题目描述

一次考试共有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]=min{f[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

标签:ref   一段   min   ace   tin   print   form   https   ||   

原文地址:https://www.cnblogs.com/Tidoblogs/p/11488601.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!