AcWing 730. 机器人跳跃问题

原题链接

考察:二分 or 递推

思路一:

          二分初始能量值,check函数检查即可.要注意的是每次E都+=E-h,也就是 E = 2*E-h. 2100000不管用什么数据类型都会爆,因此必须考虑别的做法:此时思路有二:

  1. 高精度,但是高精很慢,尽量避免高精
  2. 避开运算,在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 }

 

posted @ 2021-02-24 12:14  acmloser  阅读(77)  评论(0编辑  收藏  举报