洛谷P3957 跳房子

普及组的题.....填坑来了。

当年的我一眼二分+DP,现在都佩服起自己来了......

然后我们就写个二分,在check里面写单调队列优化DP即可。

然后就A了......

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 typedef long long LL;
 6 const int N = 500010;
 7 const LL INF = (1ll << 61);
 8 
 9 int n, x[N];
10 LL v[N], k;
11 
12 int p[N], head, top; 
13 LL f[N];
14 
15 inline bool check(int L, int R) {
16     memset(f, 0xcf, sizeof(f));
17     LL ans = -INF;
18     f[0] = 0;
19     head = 1;
20     top = 0;
21     int pos_in = 0;
22     for(int i = 1; i <= n; i++) {
23         while(x[i] - x[pos_in] >= L) {
24             p[++top] = pos_in;
25             while(head < top && f[p[top]] > f[p[top - 1]]) {
26                 p[top - 1] = p[top];
27                 top--;
28             }
29             pos_in++;
30         }
31         while(head <= top && x[i] - x[p[head]] > R) {
32             head++;
33         }
34         
35         if(head <= top) {
36             f[i] = f[p[head]] + v[i];
37         }
38         
39         ans = std::max(ans, f[i]);
40     }
41     return ans >= k;
42 }
43 
44 int main() {
45     int d;
46     LL sum = 0;
47     scanf("%d%d%lld", &n, &d, &k);
48     for(int i = 1; i <= n; i++) {
49         scanf("%d%lld", &x[i], &v[i]);
50         sum += std::max(v[i], 0ll);
51     }
52     if(sum < k) {
53         printf("-1");
54         return 0;
55     }
56     
57     int l = 0, r = std::max(x[n] - d, d), mid;
58     while(l < r) {
59         mid = (l + r) >> 1;
60         if(check(std::max(1, d - mid), d + mid)) {
61             r = mid;
62         }
63         else {
64             l = mid + 1;
65         }
66     }
67     
68     printf("%d", r);
69     return 0;
70 }
AC代码

 

posted @ 2018-10-19 11:07  huyufeifei  阅读(158)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜