嘘~ 正在从服务器偷取页面 . . .

洛谷P1868 饥饿的奶牛 题解


洛谷P1868 饥饿的奶牛 题解

题目链接:P1868 饥饿的奶牛

题意

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

现用汉语翻译为:

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

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

$1 \leq n \leq 1.5 \times 10^5$,$0 \leq x \leq y \leq 3 \times 10^6$。

设 $f_i$ 表示只考虑前 $i$ 个位置能吃到的最多牧草

这里的 $\text{Edge}(i)$ 表示以 $i$ 结尾的所有区间组成的集合

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

这样就可以枚举 $j$ 了

时间复杂度 $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;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录