730. 机器人跳跃问题
题意
跳建筑( 0 - n ),0 位置上初始能量为 e,问最少多少能力能跳完所有建筑 过程中能力不小于 0
假设机器人在第 k 个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1 个建筑。
如果 EH(k+1)>E,那么机器人就失去 EH(k+1)−E 的能量值,否则它将得到 )E−H(k+1) 的能量值。
思路
- 二分答案
坑点
- 溢出问题 (爆 long long int)
算法一:二分答案
时间复杂度
O ( l o g 2 n ) O(log_2 n) O(log2n)
实现步骤
- 二分答案
- 判断 mid 与 check (判断当前 mid 是否够走完)的关系
e - (h [ k + 1 ] - e)
==2e - h [ k + 1 ]
e + (e - h [ k + 1 ])
==2e - h [ k + 1 ]
- 可发现不管下一个建筑的大小 当前建筑的能力 在走到下一个建筑时 必然为
2e - h [ k + 1 ]
- 在过程中提前判断 中止情况(小于 0 和大于 1e5 时)
- 后面的建筑能量随着 e 的增大而增大 所以当 e 一定大时 一定能走完(这种情况不提前判断的话 不断 * 2 很快就会爆 long long)
代码
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5+10;
typedef long long ll;
int num[N];
int n;
int check(int x)
{
int res=0;
for(int i=1;i<=n;i++)
{
x=x*2-num[i];
if(x<0)
{
res++;
break;
}
if(x>1e5)
{
break;
}
// cout<<x<<" ";
}
// cout<<endl;
if(res==0)
{
return 1;
}else{
return -1;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>num[i];
}
int l=0,r=1e5+5;
while(1)
{
int mid=(l+r)/2;
if(check(mid)==1)
{
r=mid;
}else{
l=mid+1;
}
if(l==r)
{
break;
}
// cout<<l<<" "<<r<<endl;
}
cout<<r<<endl;
return 0;
}
总结
二分答案 + 小递推 需要提前判断 不然只能过4个点了