思路

神仙思路,就差一步就能想出来了。。。

看到第i个人给出的条件,发现有\(a_i\)个大于,\(b_i\)个小于并不好处理

考虑把条件转化成第i个人对应的排名处理,设第i个人的排名为\(a_i+1\),则应当有\(n-a_i-b_i\)个和第i个人成绩相同的人

数形结合一下

把第i个人的条件看成是一个区间,区间开头是\(a_i+1\),结尾是\(n-b_i\),表示排名在这段区间中的人成绩相等

当两个人说的区间不重叠的时候,两个人都可以被判为真

这里要注意两个区间可以完全重合(两个人分数一致,说的都是一样的)(我就是没考虑这个)

有两种情况不可行(必然是谎言),一是左端点大于右端点,二是有超过区间长度的人都说了一样的话(这样只有区间长度个人说了真话)

于是给每个区间赋权值表示说这个区间的人数,所以要求的就是选出一些不相交区间使得权值最大(选出的人都说真话)

dp一下

转移方程是\(dp[i]=max(dp[i-1],dp[k]+E[i].val)\),k是最后一个右端点小于i的左端点的区间

k可以二分的找到,所以复杂度是\(O(n\log n)\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int n,f[100100],a[100100],b[100100],cnt;
struct Inter{
int s,t,val;
}E[100100];
bool cmp(Inter a,Inter b){
return a.t<b.t||(a.t==b.t&&a.s<b.s);
}
int find(int l,int r,int val){
int midans=0;
while(l<=r){
int mid=(l+r)>>1;
if(E[mid].t<val)
midans=mid,l=mid+1;
else
r=mid-1;
}
return midans;
}
map<pair<int,int> , int> M;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d",&a[i],&b[i]);
int len=n-a[i]-b[i];
int lx=a[i]+1,rx=lx+len-1;
if(rx>=lx)
M[make_pair(lx,rx)]=min(rx-lx+1,M[make_pair(lx,rx)]+1);
}
for(auto it = M.begin();it!=M.end();it++){
E[++cnt].s=(*it).first.first;
E[cnt].t=(*it).first.second;
E[cnt].val=(*it).second;
}
sort(E+1,E+cnt+1,cmp);
f[1]=E[1].val;
for(int i=2;i<=n;i++)
f[i]=max(f[i-1],f[find(1,i-1,E[i].s)]+E[i].val);
printf("%d\n",n-f[n]);
return 0;
}

P2519 [HAOI2011]problem a的更多相关文章

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

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

  2. Luogu P2519 [HAOI2011]problem a

    题目链接 \(Click\) \(Here\) \(DP\)神题.以后要多学习一个,练一练智商. 关键点在于把"有\(a_i\)个人分数比我高,\(b_i\)个人分数比我低"这句话 ...

  3. 洛谷 P2519 [HAOI2011]problem a

    传送门 考虑转化为求最多说真话的人数 设$f(i)$表示排名前$i$的人中最多说真话的人的数量,考虑转移,如果由$j$转移而来,可以设$[j,i]$之间的人全都分数相等,那么式子就是$f[i]=f[j ...

  4. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

  5. bzoj 2301: [HAOI2011]Problem b

    2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MB Submit: 3757 Solved: 1671 [Submit] ...

  6. HAOI2011 problem b

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 1047  Solved: 434[Submit][ ...

  7. BZOJ 2298: [HAOI2011]problem a 动态规划

    2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...

  8. BZOJ 2301: [HAOI2011]Problem b 莫比乌斯反演

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 1007  Solved: 415[Submit][ ...

  9. 2301: [HAOI2011]Problem b

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4164  Solved: 1888[Submit] ...

随机推荐

  1. IO model

    上节的问题: 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么确定IO操作完了? 很多程序员可能会考虑使用“线程池”或“连接池”.“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程, ...

  2. django之路由分析

    URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. URLconf配置 基本格式: from django.conf.urls i ...

  3. python 类似java的三目运算符

    python中没有其他语言中的三元表达式,不过有类似的实现方法 其他语言中,例如java的三元表达式是这样 int a = 1; String b = ""; b = a > ...

  4. linux 系统监控和进程管理

    1.命令top,查看cpu和内存使用,主要进程列表和占用资源. 2.内存使用命令foree -g 3.查询所有java进程:pgrep -l java     ------ps aux|grep .j ...

  5. PDF文档导出

    代码如下: /// <summary> /// 获取html内容,转成PDF(注册) /// </summary> public void DownloadPDFByHTML( ...

  6. 如何用nginx在本地把9000端口转发到80端口上

    起因看到一个用java写的轻博客,于是就兴致冲冲的试用一下.由于是lnmp的环境,Nginx占用了80端口,新博客只能用其他的端口,这里选择了9000端口,本地测试没问题.总不能访问了域名然后在加上端 ...

  7. Android Camera2 参数调节关键字翻译集合,常用关键字解析

    https://blog.csdn.net/qq_29333911/article/details/79400617 black_level_lock黑电平补偿是否锁定当前值,或者可以自由更改.col ...

  8. linux时间修改-hwclock和date

    修改系统时间date 设定日期:date -s 月/日/年,例如设定日期为2018年12月1日,date -s 12/01/2018(年也可以是两位) 设定时间:date -s hh:mm:ss,例如 ...

  9. 标准库 time

    go语言的time包 1. 组成 time.Duration(时长,耗时) time.Time(时间点)time.C(放时间点的管道)[ Time.C:=make(chan time.Time) ]t ...

  10. uml类图和er图中主外键的表示区别

    在er图也就是数据库中,无论是mysql/oracle都是从表引用主表的pk作为外键. 而在uml类图表示法中,他们的顺序则刚好相反,从主对象导向到子对象,如下: 主体是资金借款方,征信信息和资金借款 ...