#10181. 「一本通 5.5 练习 2」绿色通道

Posted mzg1805

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#10181. 「一本通 5.5 练习 2」绿色通道相关的知识,希望对你有一定的参考价值。

$\colorcyan>>Question$

二分+$dp$(与跳房子类似)

二分答案(窗口大小),$dp$确定是否可行

$f[i]$表示到$i$($i$选)花的最少时间

$$f[i] = min_j\in[i-d-1,i-1]\left \ f[j] \right \+a[i]$$

$d$为二分的答案

注意统计是要$f[n+1]>t$才$return\;0$

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #define ll long long
 6 using namespace std; 
 7 
 8 template <typename T> void in(T &x) 
 9     x = 0; T f = 1; char ch = getchar();
10     while(!isdigit(ch)) if(ch == -) f = -1; ch = getchar();
11     while( isdigit(ch)) x = 10 * x + ch - 48; ch = getchar();
12     x *= f;
13 
14 
15 template <typename T> void out(T x) 
16     if(x < 0) x = -x , putchar(-);
17     if(x > 9) out(x/10);
18     putchar(x%10 + 48);
19 
20 //-------------------------------------------------------
21 
22 const int N = 5e4+7;
23 int n,t;
24 int a[N],f[N];
25 int q[N],hd,tl,lst;
26 
27 bool chk(int d) 
28     memset(f,0x3f,sizeof(f)); f[0] = 0;
29     hd = 1,tl = 0,lst = 0; int i;
30     for(i = 1;i <= n+1; ++i) 
31         while(lst < i-d-1) ++lst;
32         for(;lst < i; ++lst) 
33             while(hd <= tl && f[q[tl]] > f[lst]) --tl;//debug --tl -> --q[tl]
34             q[++tl] = lst;
35         
36         while(hd <= tl && q[hd] < i-d-1) ++hd;
37         f[i] = f[q[hd]] + a[i];
38         //if(f[i] > t) return 0;//debug
39     
40     if(f[n+1] > t) return 0;//debug 
41     return 1;
42 
43 
44 void bs_ans() 
45     int l = 0,r = n,ans;
46     while(l <= r) 
47         int mid = (l+r)>>1;
48         if(chk(mid)) ans = mid,r = mid-1;
49         else l = mid+1;
50     
51     out(ans);
52 
53 
54 int main() 
55     in(n); in(t); int i;
56     for(i = 1;i <= n;++i) in(a[i]);
57     bs_ans();
58     return 0;
59 

 

以上是关于#10181. 「一本通 5.5 练习 2」绿色通道的主要内容,如果未能解决你的问题,请参考以下文章

「一本通 4.1 练习 2」简单题

#10023. 「一本通 1.3 练习 2」平板涂色

#10117 「一本通 4.1 练习 2」简单题

「一本通 4.3 练习 2」花神游历各国(loj10128)

「一本通 6.3 练习 2」聪明的燕姿

「一本通 5.1 练习 2」分离与合体 题解