洛谷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;
}