CF248D Sweets for Everyone! Solution

题目链接(洛谷)
CodeForces

这是一道二分加贪心题

题意

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

思路

在这个题中,我们可以二分这个 k k 值,然后考虑怎么验证可行性。
首先一定是有糖肯定会给,然后再看如果当没有糖果时,是采取拿到满足之前的糖果数后就返回送糖果,还是最后一口气拿到足够的再返回。
如图:
在这里插入图片描述
画图技巧有限,望海涵
那么在 c h e c k ( ) 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;
}

谢谢

猜你喜欢

转载自blog.csdn.net/qq_43537070/article/details/107563752