Welcome to LHY's Blog!

枚举

1.饥饿的牛

来源:USACO 2023 February Contest Bronze
原题链接

题目描述

贝茜是一头饥饿的牛。

每天晚上,如果牛棚中还有干草的话,贝茜都会吃掉其中的一捆。

初始时,牛棚中没有干草。

为了让贝茜不被饿死,农夫约翰制定了 \(N\) 个给贝茜送干草的计划。

其中第 \(i\) 个计划是在第 \(d_i\) 天的白天给贝茜送去 \(b_i\) 捆干草。

这些计划互不冲突,保证 \(1≤d1<d2<…<dN≤T\)

请你计算,贝茜在第 \(1∼T\) 天中有多少天有干草吃。

输入格式

第一行包含两个整数 \(N\)\(T\)

接下来 \(N\) 行,每行包含两个整数 \(di\) , \(bi\)

输出格式

输出贝茜在第 \(1∼T\) 天中有干草吃的天数。

数据范围

\(1≤N≤10^5\),
\(1≤T≤10^14\),
\(1≤di≤10^14\),
\(1≤bi≤10^9\)

输入样例

2 5
1 2
5 10

输出样例

3

算法:(枚举)\(O(n)\)

算法内容

由于T的范围过大,所以不能枚举每一天,
我们可以采取枚举每一次送草的点,一共\(N\)个点

C++代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

int main()
{
    int n;
    LL T;

    scanf("%d%lld", &n, &T);
    //res记录答案
    //cur表示上一次送完草后还剩的草
    //last表示上次送草的前一天
    LL res = 0, cur = 0, last = 0;
    for (int i = 1; i <= n; i ++ ) //枚举区间右端点
    {
        LL d, b;
        scanf("%lld%lld", &d, &b);
        LL len = d - 1 - (last + 1) + 1;
        LL days = min(len, cur);

        res += days;
        cur = cur - days + b;
        last = d - 1;
    }
    
    //特殊处理最后一个区间
    res += min(cur, T - (last + 1) + 1);
    printf("%lld\n", res);
    
    return 0;
}

posted @ 2023-06-13 17:09  LiHaoyu  阅读(46)  评论(0)    收藏  举报