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 }