传送门:点击打开链接
题意:n个人,告诉你n个人的工资,每个人还有一个权值,现在从这n个人中选出m个人,使得他们的权值之和最大
思路:先按照工资从小到大排序,那么每次最优的必然是一个子区间中的值。所以我们能确定,所有的答案此时都是子区间,。所以利用尺取法O(n)求出答案
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck printf("fuck")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
const int MX = 1e5 + 5;
struct Data {
int a, b;
bool operator<(const Data &P)const {
return a < P.a;
}
} A[MX];
int main() {
int n, d; //FIN;
while(~scanf("%d%d", &n, &d)) {
for(int i = 1; i <= n; i++) {
scanf("%d%d", &A[i].a, &A[i].b);
}
sort(A + 1, A + 1 + n);
int L = 1, R = 0;
LL ans = 0, sum = 0;
while(L <= n) {
while(R + 1 <= n && A[R + 1].a - A[L].a < d) sum += A[++R].b;
ans = max(ans, sum);
sum -= A[L++].b;
}
printf("%I64d\n", ans);
}
return 0;
}