ZOJ - 4062  

题意:有n个植物排成一排,按顺序植物的编号是1-n,每个植物都有一个生长速率,有一个机器人,机器人可以走m步,每走一步,这个机器人就会浇一次水,浇一次水那个植物就会长

自身的生长速率那么高,然后现在要求最大的最小生长值,

 

思路:一般要求最大的最小值都是使用二分来求答案,我们二分出的答案做以下的测试

我们先求出每个位置大于最小值至少到达此位置几步

然后我们直接考虑当前位置是尽量往右走,走来回来增加此位置的生长速率,不过有很多细节,我们遇到负数的时候就不能往当前位置来回了,

肯定是其他的方向路线来走,不过步数基本一样,所以我们可以模拟路线步数出来,然后注意不要爆了long long

 

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,m;
ll a[100001];
bool lower(ll x)
{
    ll res=0,sum=0;
    for(int i=0;i<n;i++)
    {
        ll y=x/a[i]+(x%a[i]!=0)-res;
        if(y<=0)
        {
            if(i!=n-1) y=1;
            else y=0;
        }
        res=y-1;
        if(res<0) res=0;//如果当前的已经不需要来回了,就把右边的加上,
        sum+=res+y;//加了当前的还有旁边要走回的来回数
        if(sum>m) return false;
    }
    return true;
}
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        ll l=0,r=1e18;
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
        }
        ll x=0;
        while(l<=r)//二分出答案
        {
            ll mid=(l+r)/2;
            if(lower(mid))
            {
                x=mid;
                l=mid+1;
            }
            else{
                r=mid-1;
            }
        }
        printf("%lld\n",x);
    }
}