题意与分析(CodeForces 580B)

\(n\)个人,告诉你\(n\)个人的工资,每个人还有一个权值。现在从这n个人中选出m个人,使得他们的权值之和最大,但是对于选中的人而言,其他被选中的人的工资不能超过他的工资+d。

这题用尺取法可以漂亮的解决。尺取法按照《挑战》一书的定义,是“指对数组保存一对下标(起点和终点),然后根据实际情况交替推进两个端点直到得到答案”的一种方法,因为这种操作“很像是尺蠖(日文中称为尺取虫)爬行的方式”而得名。

具体到这题就是,都不用二分:按照工资排序后设定前后指针\(L,R\),然后将\(R\)向前移动到最大的符合条件的区间,记录并更新长度,然后将\(L\)更新,再继续这样操作即可。复杂度为\(O(n)\)。

代码

#include <bits/stdc++.h>
#define MP make_pair
#define PB emplace_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (repType i = (a); i <= (b); ++i)
#define per(i, a, b) for (repType i = (a); i >= (b); --i)
#define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
using namespace std;
using ll=long long;
using repType=ll;
const int MAXN=100000+5;
int n,d;
vector<pair<ll,ll> > vec;
int main()
{
QUICKIO
cin>>n>>d;
rep(i,1,n)
{
ll m,s; cin>>m>>s;
vec.PB(MP(m,s));
}
sort(ALL(vec));
int L=0,R=-1;
ll ans=0, sum=0;
while (L<n)
{
while(R+1<n && vec[R+1].fi-vec[L].fi<d)
sum+=vec[++R].se;
ans=max(ans,sum);
sum-=vec[L++].se;
}
cout<<ans<<endl;
return 0;
}

最新文章

  1. [DFNews] EnCase v7.08发布
  2. oracle 执行执行动态存储过程名---其实就是存储过程名是个字符串参数
  3. noi 97 积木游戏
  4. C++引用作为函数的参数
  5. 【技术帖】解决 Hudson jenkins 连接等待中 - Waiting for next av
  6. Ubuntu 查找命令
  7. 并发容器ConcurrentHashMap#put方法解析
  8. android dialog弹出的情况下监听返回键
  9. activty栈管理
  10. Android Studio 之 注释模板
  11. [Day15]常用API(Object类、String类)
  12. 8.并发容器ConcurrentHashMap#put方法解析
  13. Hadoop-1.2.1伪分布下 hive-0.10.0内嵌模式安装
  14. e870. 获取默认外观的数据
  15. Nginx+Keepalive实现高可用负载均衡
  16. Druid.io通过NiFi摄取流数据
  17. 一款纯css3实现的颜色渐变按钮
  18. [原创][C#.Winform 控件]Krypton Suite comments
  19. Python:文件操作技巧(File operation)(转)
  20. Gym - 100781A Adjoin the Networks (树的直径)

热门文章

  1. stanford core
  2. 如何查看Windows下端口占用情况
  3. 自学安卓练习作品单词APP(1)-安卓的hello word与有道字典防爬虫破解
  4. java 编写小工具 尝试 学习(三)
  5. Swift_枚举
  6. iOS 文件下载及断点续传
  7. List、LinkedList、ArrayList、Vector
  8. .Net core 还原Nuget包失败的解决方法
  9. 剑指Offer-迭代
  10. 『Python基础-12』各种推导式(列表推导式、字典推导式、集合推导式)