清北前紧急补课6饥饿的奶牛
Posted civilization-ga
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北前紧急补课6饥饿的奶牛相关的知识,希望对你有一定的参考价值。
题目描述
有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。
现用汉语翻译为:
有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草。你可以选择任意区间但不能有重复的部分。
对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。
输入输出格式
输入格式:第一行,N,如题
接下来N行,每行一个数x,y,如题
输出格式:一个数,最多能吃到的牧草堆数
输入输出样例
说明
1<=n<=150000
0<=x<=y<=3000000
3000000的数据范围开始让我RE了一个点。能看出要用DP,就需要找一个状态转移方程。
我们用f[i]表示前i个区间中牛所能吃到的最多的牧草数。
用一个strcut来记录区间,其中 cow[].x记录区间的左端点,cow[].y记录区间的右端点。ans来记录牧草堆数(前缀和)
对于区间进行排序。
接下来我们找一个状态转移方程。
要使f[i]转移的条件就是找到一个j f[j]+y[j]-x[j]+1>f[j]
可以转化成
f[cow[j].y]=max(f[cow[j].y],f[cow[j].x-1]+cow[j].ans);
可以构成状态转移方程的条件是 该j点要在n之前,且该区间的左端点等于i
有以下代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=3000100; int n; int minn,sum; int f[maxn]; struct c{ int x,y; int a,b; int ans; }cow[maxn]; bool cmp(c a,c b){ return a.x==b.x?a.y<b.y:a.x<b.x; } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>cow[i].x>>cow[i].y; cow[i].ans=cow[i].y-cow[i].x+1; minn=max(minn,cow[i].y);//寻找区间最右端 } sort(cow+1,cow+n+1,cmp); int j=1; for(int i=0;i<=minn;i++){ f[i]=max(f[i],f[i-1]); while(j<=n&&cow[j].x==i){ f[cow[j].y]=max(f[cow[j].y],f[cow[j].x-1]+cow[j].ans); j++; } sum=max(f[i],sum); } cout<<sum; }
以上是关于清北前紧急补课6饥饿的奶牛的主要内容,如果未能解决你的问题,请参考以下文章