CF248D Sweets for Everyone! Solution

题目链接(洛谷)
CodeForces

这是一道二分加贪心题
题意

在一条路上有若干个店和房子,每个房子要放一个糖果,每经过一个商店可以得到一个一个糖果。
现在我们开始可以携带 k k k个糖果,要求在 t t t时间内完成,求这个 k k k的最小值。

思路

在这个题中,我们可以二分这个 k k k值,然后考虑怎么验证可行性。
首先一定是有糖肯定会给,然后再看如果当没有糖果时,是采取拿到满足之前的糖果数后就返回送糖果,还是最后一口气拿到足够的再返回。
如图:
在这里插入图片描述
画图技巧有限,望海涵
那么在 c h e c k ( ) check() check()中考虑这两个情况,可以知道一定只有一次会选择走到底再走回去。
所以直接二分这个方法修改点,就ok了

代码

具体实现见代码

bool check(int x)
{
    int cnt = 0, pos1 = 0, pos2 = 0, sub = 0, s = t;
    for (int i = 1; i <= n; i++)
    {
        if (cnt == sum && x >= 0)
            return s >= min(i - pos1, sub);
        s--;
        if (str[i] == 'H')
        {
            if (!x)
            {
                if (!pos1)
                    pos1 = i;
                pos2 = i;
            }
            x--;
            cnt++;
        }
        else if (str[i] == 'S')
        {
            x++;
            if (!x)
            {
                sub += i - pos2;
                if (cnt != sum)
                    sub += i - pos2;
            }
        }
    }
    return s >= min(n - pos1, sub) && x >= 0;
}
int main()
{
    rd(n), rd(t);
    scanf ("%s", str + 1);
    for (int i = 1; i <= n; i++)
        sum += str[i] == 'H';
    int l = 0, r = sum;
    while (l < r)
    {
        int mid = (l + r) >> 1;
        if (check(mid))
            r = mid;
        else
            l = mid + 1;
    }
    if (check(l))
        pt(l);
    else
        pt(-1);
    return 0;
}
谢谢
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值