bzoj5438: 青蛙

考虑青蛙的位置始终都是在一个区间里面。

每次是最前面的那只青蛙往下一个没有到达的位置跳。

我们可以求出最多可以有几只青蛙这么跳,把代价最大的扔进去。

如果没有方法可以这么跳,选择代价最小的把所有点跳完,其余的从1跳到n即可。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define M 100010
 4 #define LL long long
 5 int c[M], a[M];
 6 inline void solve() {
 7     int n, m, k, d;
 8     scanf("%d%d%d%d", &n, &m, &k, &d);
 9     for(int i = 1; i <= m; ++ i) {
10         scanf("%d", &c[i]);
11     }
12     for(int i = 1; i <= k; ++ i) {
13         scanf("%d", &a[i]);
14     }
15     a[++ k] = 1; a[++ k] = n;
16     sort(c + 1, c + m + 1);
17     sort(a + 1, a + k + 1);
18     int lim = 2147483647, r = 1;
19     for(int i = 1; i <= k; ++ i) {
20         r = max(r, i);
21         while(a[r + 1] - a[i] <= d && r < k) ++ r;
22         lim = min(lim, r - i + 1);
23         if(r == k) break;
24     }
25     -- lim;
26     //cerr << "num " << lim << endl;
27     /*for(int i = 1; i <= k; ++ i) {
28         printf("%d ", a[i]);
29     }
30     puts("");*/
31     if(lim == 0) {
32         LL Ans = 0;
33         for(int i = 1; i < k; ++ i) {
34             if(a[i + 1] - a[i] > d) {
35                 Ans += c[1];
36             }
37         }
38         for(int i = 2; i <= m; ++ i) {
39             Ans += c[i];
40         }
41         printf("%lld\n", Ans);
42         return;
43     }
44     m -= lim;
45     if(n - 1 <= d) {
46         puts("0");
47         return;
48     }
49     LL Ans = 0;
50     for(int i = 1; i <= m; ++ i) {
51         Ans += c[i];
52     }
53     printf("%lld\n", Ans);
54 }
55 int main() {
56     int T;
57     scanf("%d", &T);
58     while(T --) {
59         solve();
60     }
61 }

 

posted @ 2018-09-01 20:55  iamunstoppable  阅读(282)  评论(0编辑  收藏  举报