-
E - Plants vs. Zombies
- ZOJ - 4062
- 题意:机器人走过一个花,可以给那个花浇水,给定步数下,问花的最小的最大能量值
- 思路:最大化最小值常见二分类型。直接二分答案,然后从前往后计算每个点满足答案要多少次。
- 我们跟它右边那个反复跳即可。这样的话每一次check先预处理出实际应该遍历这个点几次,
- 到达一个点时先sum++,因为第一次总是要从前面过来的,不是在后面循环过程中凑出来的,
- 每次都是向右循环凑次数:
-
sum+=(b[i]-1)*2
- 所以每一次需要走的次数应当减去上次循环过程中已经走过的,
-
b[i+1]-=(b[i]-1);
- 然后记录需要使用跳多少次即可。最后只需判断次数是否大于m即可,
- 如果到了最后需要判断是否需要sum++
-
if(i==n&&b[i]<1)break;
-
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 123456 int t,n,a[maxn],maxx; ll m,l,r,mid,b[maxn]; bool check(ll middle) { ll sum=0; for(int i=1; i<=n; i++) b[i]=(middle%a[i]==0?middle/a[i]:middle/a[i]+1); for(int i=1; i<=n; i++) { if(i==n&&b[i]<1)break; sum++; if(b[i]>1) { sum+=(b[i]-1)*2; b[i+1]-=(b[i]-1); } if(sum>m)return false; } return true; } int main() { scanf("%d",&t); while(t--) { l=r=maxx=0; scanf("%d%lld",&n,&m); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); if(a[i]>maxx) maxx=a[i]; } r=maxx*m; while(l<r) { mid=(r+l+1)/2; if(check(mid))l=mid; else r=mid-1; } printf("%lld\n",r); } return 0; }
E - Plants vs. Zombies ZOJ - 4062 -二分(最小值最大化)
最新推荐文章于 2019-07-23 20:41:17 发布