P2519 [HAOI2011]problem a
思路
神仙思路,就差一步就能想出来了。。。
看到第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的更多相关文章
- [luogu] P2519 [HAOI2011]problem a (贪心)
P2519 [HAOI2011]problem a 题目描述 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同 ...
- Luogu P2519 [HAOI2011]problem a
题目链接 \(Click\) \(Here\) \(DP\)神题.以后要多学习一个,练一练智商. 关键点在于把"有\(a_i\)个人分数比我高,\(b_i\)个人分数比我低"这句话 ...
- 洛谷 P2519 [HAOI2011]problem a
传送门 考虑转化为求最多说真话的人数 设$f(i)$表示排名前$i$的人中最多说真话的人的数量,考虑转移,如果由$j$转移而来,可以设$[j,i]$之间的人全都分数相等,那么式子就是$f[i]=f[j ...
- BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4032 Solved: 1817[Submit] ...
- bzoj 2301: [HAOI2011]Problem b
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MB Submit: 3757 Solved: 1671 [Submit] ...
- HAOI2011 problem b
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 1047 Solved: 434[Submit][ ...
- BZOJ 2298: [HAOI2011]problem a 动态规划
2298: [HAOI2011]problem a Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...
- BZOJ 2301: [HAOI2011]Problem b 莫比乌斯反演
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 1007 Solved: 415[Submit][ ...
- 2301: [HAOI2011]Problem b
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4164 Solved: 1888[Submit] ...
随机推荐
- Python并发编程之线程池/进程池--concurrent.futures模块
一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...
- HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor
看到的最长的类名: HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhere ...
- plsql 代码自动补全
1.新建一个文件,命名不限定,文件内容为自动补全内容,比如: i=INSERTu=UPDATEs=SELECTf=FROMw=WHEREo=ORDER BYd=DELETEdf=DELETE FROM ...
- django models数据库操作
一.数据库操作 1.创建model表 基本结构 1 2 3 4 5 6 from django.db import models class userinfo(models.M ...
- JAVA基础2---深度解析A++和++A的区别
我们都知道JAVA中A++和++A在用法上的区别,都是自增,A++是先取值再自增,++A是先自增再取值,那么为什么会是这样的呢? 1.关于A++和++A的区别,下面的来看个例子: public cla ...
- 复习loadRunner参数化
参数化: 为什么要用参数化? 如果是单一数据,那么会纯测试缓存. 如果是参数化,基本上大部分数据不会被缓存命中. 极端情况:所有的数据都不会被缓存命中,或者少量命中. 在loadrunner中,所有的 ...
- Anaconda下载及安装及查看安装的Python库用法
Anaconda下载及安装及查看安装的Python库用法 Anaconda 是一个用于科学计算的 Python 发行版,提供了包管理与环境管理的功能.Anaconda 利用 conda 来进行 pac ...
- Javascript原生之用cssText批量修改样式
一般情况下我们用js设置元素对象的样式会使用这样的形式: var element= document.getElementById(“id”);element.style.width=”20px”;e ...
- show processlist命令与kill 线程
show [full] processlist show processlist显示正在运行的线程.如果有process权限,则可以查看所有正在运行的线程.否则,只能看到自己的线程.如果不使用full ...
- python通过sftp远程传输文件
python提供了一个第三方模块paramiko,通过这个模块可以实现两台机器之间的网络连接,sftp是paramiko的一个方法,使用sftp可以在两台机器之间互相传输 拷贝文件.然而paramik ...