782. 避嫌抢劫
题目描述
小镇沿街分布(可以理解为都在数轴上),有n家银行(位置以数轴的坐标表示,金额表示可以被抢走的金额)。
两个绑匪试图分别抢劫一个银行,为了让警方多奔波他们商定选择的两个银行距离不小于d。
请问,符合约定的情况下他们能抢到的总金额最大是多少。
输入格式
输入包含 n+1 行。
第一行包含两个整数 n 和 d,分别表示银行的数量和约定的距离。
接下来 n 行,每行包含两个整数 a 和 b ,分别表示坐标和金额。
输出格式
输出一个数字表示可以获得的最大金额。
数据范围
1≤n≤2∗105,
1≤d,a,b≤108
注意:数据中保证至少存在两个银行之间的距离不小于 d。
输入样例:
6 3
1 1
3 5
4 8
6 4
10 3
11 2
输出样例:
11
思路
双指针算法.
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; typedef pair<int, int> PII; const int max_n=2e5+5; PII a[max_n]; int main() { int n, d, res=0;//银行的数量,约定的距离,可获得的最大金额 cin>>n>>d; for(int i=0; i<n; i++) cin>>a[i].first>>a[i].second; sort(a, a+n); int p=0, q=1;//设置两个指针p, q,p指向第一个银行 while(q<n && a[q].first-a[p].first<d) q++;//q指向找到的第一个与p的距离>=d的银行; if(q<n) { int maxp=a[p].second;//记录p遇到的银行最大金额值 for(; q<n; q++) {//q向后移动 while(p<q && a[q].first-a[p].first>=d) maxp=max(maxp, a[p++].second);//p向后移动至离q最近的 距离>=d的银行,并在移动过程中更新maxp res=max(res, maxp+a[q].second); } } cout<<res<<endl; return 0; }