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。没时间写了,刷专题去了。。。等刷到二分专题再回过头来刷这题。