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

[luogu] P2519 [HAOI2011]problem a (贪心)

时间:2019-04-07 21:43:14      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:code   ccf   ons   ret   int   space   ble   暴力   names   

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

题解

本题因为过度巧妙引起极度不适。
看题十分钟。。。暴力都不会。
日常开题解。

我只想到了对于一个人,
\([a_i+1,n-b_i]\)内累计人数超过的这个区间的就不算了。
还有本身矛盾的就是\(a_i+b_i>=n\)
然后怎么做啊。。。
一看题解,做完了。。。
我们把人转为\([a_i+1,n-b_i]\)的区间以后,这个区间有一个价值,就是当前描述位于这个区间合法(有没有多于这个区间)的人数。
然后dp求一下第i个人时的最大值就可以了。

\(f[i]=max(f[i-1],f[next]+val);\)

Code

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<map>
#include<vector>
using namespace std;
const int N=1e6+5;
int n,f[N];
vector<int>q[N];
map<pair<int,int>,int>mp;

int read(){
    int x=0,w=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}

int main(){
    n=read();
    for(int i=1;i<=n;i++){
        int l=read(),r=read();
        l++;r=n-r;
        if(l>r)continue;
        if(++mp[make_pair(l,r)]==1)
            q[r].push_back(l);
    }
    for(int i=1;i<=n;i++){
        f[i]=f[i-1];
        for(int j=0;j<q[i].size();j++)
        f[i]=max(f[i],f[q[i][j]-1]+min(i-q[i][j]+1,mp[make_pair(q[i][j],i)]));
    }
    cout<<n-f[n]<<endl;
    return 0;   
} 

[luogu] P2519 [HAOI2011]problem a (贪心)

标签:code   ccf   ons   ret   int   space   ble   暴力   names   

原文地址:https://www.cnblogs.com/hhh1109/p/10667114.html

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