AcWing 730. 机器人跳跃问题
考察:二分 or 递推
思路一:
二分初始能量值,check函数检查即可.要注意的是每次E都+=E-h,也就是 E = 2*E-h. 2100000不管用什么数据类型都会爆,因此必须考虑别的做法:此时思路有二:
- 高精度,但是高精很慢,尽量避免高精
- 避开运算,在E一定满足条件就return 1
可以发现当E = hmax时,它的再次运算一定>hmax所以在check途中检查hmax即可.
1 #include <iostream> 2 using namespace std; 3 const int N = 100010; 4 int h[N],n,maxn; 5 bool check(int mid) 6 { 7 for(int i=1;i<=n;i++) 8 { 9 if(h[i]>mid) mid -= h[i]-mid; 10 else mid+=mid-h[i]; 11 if(mid<0) return false; 12 if(mid>=maxn) return 1; 13 } 14 return true; 15 } 16 int main() 17 { 18 int r = 0,l = 0; 19 scanf("%d",&n); 20 for(int i=1;i<=n;i++) scanf("%d",&h[i]),r= r+h[i],maxn = max(h[i],maxn); 21 while(l<r) 22 { 23 int mid = l+r>>1; 24 if(mid>=maxn||check(mid)) r = mid; 25 else l = mid+1; 26 } 27 printf("%d\n",r); 28 return 0; 29 }
思路二:
可以发现跳跃后机器人的能量为2*E-h.能量要求最少,就是达到最后一个建筑时E = 0,此时可以递推回去,但是注意h+E后不一定恰好是2的倍数.此时需要将(h+E后)/2+1.
具体可参考样例三.
1 #include <iostream> 2 using namespace std; 3 const int N = 100010; 4 int h[N],n; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) scanf("%d",&h[i]); 9 int ans = 0; 10 for(int i=n;i>=1;i--) 11 { 12 int t = h[i]+ans; 13 if(t%2==0) ans = t/2; 14 else ans = t/2+1; 15 } 16 printf("%d\n",ans); 17 return 0; 18 }