CF #256 div2

2014-07-18 11:13:14

这次div2很热闹。。足足有4000+人(虽然有很多高rating的不算排名=。=)

A,B不多说了,来说说C,D吧。

C:由于通神早早用RMQ高效的A了C题,我也转战RMQ解法,在最后2分钟绝杀AC了,但是在重判中WA了。。。原因就在于没有在递归过程中用贪心策略:如果横着刷的次数比把所有木板竖着刷的次数

大的话用竖着刷(刷的次数 = 木板数)。。。调了很久,终于出来了。

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 int h,n,a[5005],d[5005][100];
 5 void RMQ_init(){
 6     for(int i = 0; i < n; ++i) d[i][0] = a[i];
 7     for(int j = 1; (1 << j) <= n; ++j)
 8         for(int i = 0; i + (1 << j) - 1 < n; ++i)
 9             d[i][j] = min(d[i][j - 1],d[i + (1 << (j - 1))][j - 1]);
10 }
11 int RMQ(int L,int R){
12     int k = 0;
13     while((1 << (k + 1)) <= R - L + 1) ++k;
14     return min(d[L][k],d[R - (1 << k) + 1][k]);
15 }
16 
17 int Solve(int hi,int l,int r){
18     while(a[l] < hi && l <= r) ++l;
19     while(a[r] < hi && l <= r) --r;
20     if(l > r)   return 0;
21     if(l == r)  return 1;
22     int tmin = RMQ(l,r) - hi + 1;
23     int res = tmin;
24     if(tmin <= 0){
25         int st = -1;
26         for(int i = l; i <= r; ++i){
27             if(st == -1 && a[i] >= hi){
28                 st = i;
29             }
30             if(st != -1 && (a[i] < hi || i == r)){
31                 if(i != r)  res += Solve(hi,st,i - 1);
32                 else res += Solve(hi,st,i);
33                 st = -1;
34             }
35         }
36     }
37     else{
38         if((r - l + 1)  >= a[l] - hi + 1)   res += Solve(hi + tmin,l,r);
39         else    res = 1 + Solve(hi,l + 1,r);
40     }
41     return min(res,r - l + 1);
42 }
43 int main(){
44     scanf("%d",&n);
45     h = 0;
46     for(int i = 0; i < n; ++i){
47         scanf("%d",&a[i]);
48         h = max(h,a[i]);
49     }
50     RMQ_init();
51     printf("%d\n",min(Solve(1,0,n - 1),n));
52     return 0;
53 }

D:比赛时过了A就看D去了,没啥思路。赛后看题解知道是简单二分!!!十几行的问题。。QAQ。没时间写了,刷专题去了。。。等刷到二分专题再回过头来刷这题。

posted @ 2014-07-18 11:19  Naturain  阅读(116)  评论(0编辑  收藏  举报