Plants vs. Zombies【二分答案】

题目链接


  题意:有N盆花,现在有一个浇花机器人,当它走到一个花盆面前的时候,可以给该花浇对应的a[i]的权值的防御值(植物大战僵尸嘛),然后呢,机器人一共可以走M步,问最后防御权值最小的花的最大权是多少,最小值最大问题。(机器人一开始处于位置0,花是1~N)

  首先,二分答案是比较好想到的,就是check的时候,条件是真的多,譬如说,我们走到一个花,它还需要浇水,那么可以i、i+1、i、i+1、……这样来回的走,但是如果最后一个花,花N的时候,那么就有可能它不需要浇了,这里需要判断一下,再者,如果是中间步骤的时候,步数超过M了,需要立马判断掉。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e5 + 7;
int N;
ll M, a[maxN], t[maxN];
bool check(ll lim)
{
    for(int i=1; i<=N; i++)
    {
        t[i] = (lim + a[i] - 1LL) / a[i];
        if(t[i] >= M) return false;
    }
    ll step = 0;
    for(int i=1; i<=N; i++)
    {
        if(i == N && t[N] <= 0) return true;
        step++; t[i]--;
        if(step > M) return false;
        if(t[i] <= 0) continue;
        step += t[i] * 2LL;
        if(step > M) return false;
        t[i + 1] -= t[i];
    }
    return true;
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%d%lld", &N, &M);
        for(int i=1; i<=N; i++) scanf("%lld", &a[i]);
        ll l = 1, r = 1e17 + 10, mid = 0, ans = 0;
        while(l <= r)
        {
            mid = (l + r) / 2LL;
//            mid = 4;
            if(check(mid))
            {
                l = mid + 1;
                ans = mid;
            }
            else r = mid - 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值