loj 10181 绿色通道

分析

最大值最小,考虑二分

当状态太多,就可以考虑二分分掉一个状态;

剩下的就好办了,不过注意边界&初值

代码

 1 /***********************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem:loj 10181
 5 Algorithm: 
 6 ***********************/
 7 
 8 #include<bits/stdc++.h>
 9 
10 using namespace std;
11 
12 const int maxn = 5e4 + 5;
13 
14 int n,t;
15 int a[maxn],q[maxn];
16 int dp[maxn][3];
17 
18 template<class T>inline void read(T &x){
19     x = 0;bool flag = 0;char ch = getchar();
20     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
21     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
22     if(flag) x = -x;
23 }
24 
25 template<class T>void putch(const T x){
26     if(x > 9) putch(x / 10);
27     putchar(x % 10 | 48);
28 }
29 
30 template<class T>void put(const T x){
31     if(x < 0) putchar('-'),putch(-x);
32     else putch(x);
33 }
34 
35 void file(){
36     freopen("10181.in","r",stdin);
37     freopen("10181.out","w",stdout);
38 }
39 
40 void readdata(){
41     read(n);read(t);
42     for(int i = 1;i <= n; ++ i) read(a[i]);
43 }
44 
45 bool check(int x){
46     int l,r;
47     l = r = 0;
48     dp[0][0] = 0;
49     dp[0][1] = 0;//初始化 
50     for(int i = 1;i <= n; ++ i){
51         while(l < r && q[l] < i - x) l++;
52         dp[i][1] = min(dp[i-1][0],dp[i-1][1]) + a[i];
53         if(l < r) dp[i][0] = dp[q[l]][1];
54         if(i <= x) dp[i][0] = 0;//注意初值 
55         while(l < r && dp[q[r-1]][1] >= dp[i][1]) r--;
56         q[r++]=i;
57     }
58     int ans = min(dp[n][0],dp[n][1]);
59     if(ans <= t) return 1;
60     else return 0;
61 }
62 
63 void work(){
64     int l = 0,r = n,ans = 0;
65     while(l <= r){
66         int mid = (l + r) >> 1;
67         if(check(mid)) ans = mid,r = mid - 1;
68         else l = mid + 1;
69     } 
70     put(ans);
71 }
72 
73 int main(){
74 //    file();
75     readdata();
76     work();
77     return 0;
78 }
View Code
原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11463079.html