原题
题目描述
有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。
现用汉语翻译为:
有 N 个区间,每个区间x,y 表示提供的x∼y 共y−x+1 堆优质牧草。你可以选择任意区间但不能有重复的部分。
对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。
输入格式
第一行一个整数 N。
接下来 N 行,每行两个数x,y,描述一个区间。
输出格式
输出最多能吃到的牧草堆数。
输入输出样例
输入 #1
3 1 3 7 8 3 4
输出 #1
5
说明/提示
解题思路
动态加二分。
构造一个结构体存储元素,然后按照r从小到大排序。
dp[i]=max(dp[i-1],dp[lower_bound(1,i,cow[i].l)]+cow[i].val)
lower_bound(二分查找) 最后一个没有和cow[i].l相交的元素,寻找到后取最大的那个区间。
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1.5e5+5;
struct Cow{
int l,r;
int val;
bool operator <(const Cow b){
return r<b.r;
}
}cow[N];
int n,dp[N];
int lower_bound(int l,int r,int k){
int ans=0;
while(l<r){
int mid=(l+r)>>1;
if(cow[mid].r<k) {
ans=mid;
l=mid+1;
}
else r=mid;
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d",&cow[i].l,&cow[i].r);
cow[i].val=cow[i].r-cow[i].l+1;
}
sort(cow+1,cow+n+1);
for(int i=1;i<=n;i++){
dp[i]=max(dp[i-1],dp[lower_bound(1,i,cow[i].l)]+cow[i].val);
}
printf("%d",dp[n]);
return 0;
}