洛谷P1868 饥饿的奶牛 题解

洛谷P1868 饥饿的奶牛 题解

题目链接:P1868 饥饿的奶牛

题意

有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。

现用汉语翻译为:

N N N 个区间,每个区间 x , y x,y x,y 表示提供的 x ∼ y x\sim y xy y − x + 1 y-x+1 yx+1 堆优质牧草。你可以选择任意区间但不能有重复的部分。

对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。

1 ≤ n ≤ 1.5 × 1 0 5 1 \leq n \leq 1.5 \times 10^5 1n1.5×105 0 ≤ x ≤ y ≤ 3 × 1 0 6 0 \leq x \leq y \leq 3 \times 10^6 0xy3×106

f i f_i fi 表示只考虑前 i i i 个位置能吃到的最多牧草
f i = max ⁡ j ∈ Edge ( i ) { f j − 1 + i − j + 1 } f_i = \max_{j \in \text{Edge}(i)}\left\{f_{j-1} + i-j+1\right\} fi=jEdge(i)max{fj1+ij+1}
这里的 Edge ( i ) \text{Edge}(i) Edge(i) 表示以 i i i 结尾的所有区间组成的集合

对于每个区间 [ x , y ] [x,y] [x,y] ,我们建一条 y → x y \to x yx 的边

这样就可以枚举 j j j

时间复杂度 O ( m ) O(m) O(m)

代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <random>
using namespace std;
// #define int long long
// #define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(1.5e5+15)
#define M (int)(3e6+15)
struct Edge{int u,v,next;}e[N];
int n,l,pos=1,f[M],head[M];
void addEdge(int u,int v)
{
    e[++pos]={u,v,head[u]};
    head[u]=pos;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> n;
    for(int i=1,u,v; i<=n; i++)
    {
        cin >> u >> v;
        addEdge(v,u);
        l=max(l,v);
    }
    for(int u=1; u<=l; u++)
    {
        f[u]=f[u-1];
        for(int i=head[u]; i; i=e[i].next)
        {
            int v=e[i].v;
            f[u]=max(f[u],f[(!v)?0:v-1]+(u-v+1));
        }
    }
    cout << f[l] << '\n';
    return 0;
}

转载请说明出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值