题目传送门
目录Farmer John 沿着一条高速公路拥有一个很长的农场,可以被看作类似于一维数轴。沿着农场有 \(K\) 块草地(\(1 \leq K \leq 2\cdot 10^5\));第 \(i\) 块草地位于位置 \(p_i\) 并具有美味值 \(t_i\)(\(0\le t_i\le 10^9\))。Farmer John 的死对头 Farmer Nhoj 已经将他的 \(M\) 头奶牛(\(1 \leq M \leq 2\cdot 10^5\))放在了位置 \(f_1 \ldots f_M\) 。所有这些 \(K+M\) 个位置均是 \([0,10^9]\) 范围内的不同整数。
(资料图片仅供参考)
Farmer John 需要选择 \(N\)(\(1\le N\le 2\cdot 10^5\))个位置(不一定是整数)放置他的奶牛。这些位置必须与 Farmer Nhoj 的奶牛已经占用的位置不同,但是 Farmer John 可以将他的奶牛放在与草地相同的位置。
拥有最靠近某个草地的奶牛的农夫拥有这一草地。如果来自两方农夫的两头奶牛距这一草地相等,则 Farmer Nhoj 拥有该草地。
给定 Farmer Nhoj 的奶牛的位置以及草地的位置和美味值,求 Farmer John 的奶牛以最优方式放置时可以达到的最大总美味值。
输入的第一行包含 \(K\)、\(M\) 和 \(N\)。
以下 \(K\) 行每行包含两个空格分隔的整数 \(p_i\) 和 \(t_i\)。
以下 \(M\) 行每行包含一个整数 \(f_i\)。
输出一个整数,表示最大总美味值。注意这个问题的答案可能无法用 32 位整数型存储,你可能需要使用 64 位整数型(例如,C 或 C++ 中的 "long long")。
6 5 20 44 68 1010 812 1213 14235711
36
【样例解释】
如果 Farmer John 将奶牛放在位置 \(11.5\) 和 \(8\) 则他可以得到总美味值 \(10+12+14=36\)。
先按照坐标排序
找出要占领每个草堆的最小距离,以这个为半径记录一条线段
暴力查找被最多线段覆盖的点
有一些小细节,自己看一下就好了。
#include #define LL long long#define fu(x , y , z) for(int x = y ; x <= z ; x ++)using namespace std;const int N = 2e5 + 5;const LL inf = 1e18 + 5;LL ans;LL k , m , n , cow[N] , tot = 1 , v[N];struct node { LL p , t;} re[N];struct Q { LL l , r , t;} q[N];bool cmp(node x , node y) { return x.p < y.p; }bool cmp2(Q x , Q y) { if (x.l < y.l) return 1; if (x.l == y.l && x.r < y.r) return 1; else return 0;}int main () { scanf ("%lld%lld%lld" , &k , &m , &n); fu (i , 1 , k) scanf ("%lld%lld" , &re[i].p , &re[i].t); fu(i , 1 , m) scanf ("%lld" , &cow[i]); sort (re + 1 , re + k + 1 , cmp) , sort (cow + 1 , cow + m + 1); fu (i , 1 , k) { int r = upper_bound(cow + 1 , cow + m + 1 , re[i].p) - cow; int l = r - 1; if (r == 1) q[i].l = max (0ll , re[i].p - (cow[r] - re[i].p)) , r = cow[r]; else if (r == m + 1) q[i].l = cow[l] , q[i].r = min (re[i].p + re[i].p - cow[l] , inf); else if (re[i].p - cow[l] <= cow[r] - re[i].p) q[i].l = cow[l] , q[i].r = min (re[i].p + (re[i].p - cow[l]) , inf); else q[i].l = max (0ll , re[i].p - (cow[r] - re[i].p)) , q[i].r = cow[r]; q[i].t = re[i].t; } sort (q + 1 , q + k + 1 , cmp2); v[tot] = q[1].t; fu (i , 2 , k) { if (q[i].l < q[i - 1].r) v[tot] += q[i].t , q[i].r = q[i - 1].r; else v[++tot] += q[i].t; } sort (v + 1 , v + tot + 1); int o = 0; for (int i = tot ; i >= 1 ; i --) { ans += v[i]; o ++; if (o == n) printf ("%lld" , ans) , exit (0); }}
标签:
X 关闭
X 关闭