E Plants vs. Zombies
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4062
题意
直接转思路8 QAQ
思路
植物最多生长高度为s数组中的最大值 * 机器人步数直接二分答案
给定一个最低高度,如何让机器人走的方式最优,我们会发现当该个植物需要浇n次水时我们每浇一次就向→走一步,那么这样能让机器人的步数达到最优化,
首先我们有了最低高度,那么每一次植物至少浇多少次水,除一下就出来了若为 n 次,按照我们之前的走法,会发现这个n次,会有n-1浇在了下一个地方,那么二分的check函数就十分容易写出了
代码比较丑,随便看看
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
inline long long read()
{
register long long c = getchar(), fg = 1, sum = 0;
while(c > '9' || c < '0' )
{
if(c == '-')fg = -1;
c = getchar();
}
while(c <= '9' && c >= '0')
{
sum = sum*10+c-'0';
c = getchar();
}
return fg*sum;
}
const int maxn = 1e5+7;
ll n, m, mm, ans;
ll a[maxn],d[maxn];
bool check(ll p)
{
ll sum=0ll,temp=0ll,tempn=0ll;
for(int i = 0; i < n; i++){
if(p%a[i])temp=p/a[i]+1ll;
else temp=p/a[i];
temp-=tempn;
if(temp<=0ll){
if(i!=n-1)
{temp=1ll;}
else {temp=0ll;}
tempn=0ll;
}
else tempn=temp-1ll;
sum+=temp+tempn;
if(sum>m)return false;
}
return true;
}
int main()
{
int T;
T = read();
while(T--)
{
n = read(); m = read();
for(int i = 0; i < n; i++)
{
a[i] = read();
}
ll l = 1, r = 1e18;
while(l <= r)
{
ll mid = (l+r)>>1;
if(check(mid))
{
l = mid+1;
}
else r = mid-1;
}
printf("%lld\n", l-1);
}
return 0;
}