尺取法 Codeforces580B Kefa and Company

传送门:点击打开链接

题意: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;
}


你可能感兴趣的:(尺取法 Codeforces580B Kefa and Company)