携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
饥饿的奶牛
题目描述
有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。
现用汉语翻译为:
有 个区间,每个区间 表示提供的 共 堆优质牧草。你可以选择任意区间但不能有重复的部分。
对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。
输入格式
第一行一个整数 。
接下来 行,每行两个数 ,描述一个区间。
输出格式
输出最多能吃到的牧草堆数。
样例 #1
样例输入 #1
3
1 3
7 8
3 4
样例输出 #1
5
提示
,。
动态规划
首先不妨想象这些草地是一个一个的格子。
先从最简单的定义想起:
设f[i]表示前 i 个格子最多能吃到多少牧草。
f[i]=max(f[i-1],f[j]+a[i].tail-a[i].head+1);//j表示尾小于当前区间头且f最大的区间下标
但是怎么对于所有的 j 都知道对应的所有的 i 呢?
发现一个 jj所对应的 i 的个数是不固定的,所以想到用 std::vector<int> 保存。
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>beg[3000010];
int n,mx,f[3000010];//mx 代表最大的 y,f 就是 dp 用的数组
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
beg[y].push_back(x-1);//这里保存的是 x-1,后面会比较方便
mx=max(mx,y);
}
for(int i=1;i<=mx;i++){
f[i]=f[i-1];//先设定为 f[i-1],后面再更新
for(int j=0;j<beg[i].size();j++){
int b=beg[i][j];
f[i]=max(f[i],f[b]+i-b);//这里会比较方便
}
}
printf("%d\n",f[mx]);
return 0;
}