ZOJ4062Plants vs. Zombies(二分)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ4062Plants vs. Zombies(二分)相关的知识,希望对你有一定的参考价值。
题意:有n个植物排成一排,标号为1-n,每株植物有自己的生长速度ai,每对植物浇一次水,该株植物就长高ai,
现在机器人从第0个格子出发,每次走一步,不能停留,每一步浇一次水,总共可以走m步,问最矮的植物最高是多少。
n<=1e6,sigma n<=1e7,0<=m<=1e12,1<=a[i]<=1e5
思路:7Y……你不死谁死
显然最小值最大可以二分,二分答案,最优的策略一定是从左到右依次左右横跳,直到当前格子不小于二分的值
一个致命的细节:最后一个如果在倒数第二个左右横跳的时候已经够了则不需要再走到了
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 110000 21 #define M 51 22 #define MOD 1000000007 23 #define eps 1e-8 24 #define pi acos(-1) 25 #define oo 1010000000 26 27 ll a[N],b[N],m; 28 int n; 29 30 int isok(ll k) 31 { 32 for(int i=1;i<=n+1;i++) b[i]=0; 33 ll t=0; 34 for(int i=1;i<=n;i++) 35 { 36 if(i==n&&b[n]>=k) continue; 37 t++; 38 if(t>m) return 0; 39 b[i]+=a[i]; 40 if(b[i]<k) 41 { 42 ll tmp=(k-b[i])/a[i]; 43 if(tmp*a[i]+b[i]<k) tmp++; 44 t=t+tmp*2; 45 if(t>m) return 0; 46 b[i]+=a[i]*tmp; 47 b[i+1]+=a[i+1]*tmp; 48 } 49 } 50 if(t>m) return 0; 51 return 1; 52 } 53 54 int main() 55 { 56 int cas; 57 scanf("%d",&cas); 58 for(int v=1;v<=cas;v++) 59 { 60 scanf("%d%lld",&n,&m); 61 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 62 ll l=1; 63 ll r=1e17; 64 ll last=0; 65 while(l<=r) 66 { 67 ll mid=(l+r)/2; 68 if(isok(mid)){last=mid; l=mid+1;} 69 else r=mid-1; 70 } 71 printf("%lld ",last); 72 } 73 return 0; 74 } 75
以上是关于ZOJ4062Plants vs. Zombies(二分)的主要内容,如果未能解决你的问题,请参考以下文章
zoj4062 Plants vs. Zombies 二分+模拟(贪心的思维)
ZOJ 4062 - Plants vs. Zombies - [二分+贪心][2018 ACM-ICPC Asia Qingdao Regional Problem E]