题意
在n个区间里取若干个区间,使它们互不重合且覆盖长度最大
标签给的很明确了就是dp,线性
思路
用vector记录每一个右端点的左端点
遍历右端点
再遍历它的左端点
两种情况:
- 如果这段区间要取,就要取这段区间之前的最大值+区间长度
- 如果不取,就是算出来的上一个最大值(即右端点前一个)
所以dp方程:
dp[右端点]=max(dp[右端点],dp[左端点-1]+区间长度)
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 3000010;
vector<int> a[N];
int dp[N];
int main(){
int n;
cin>>n;
int maxn=INT_MIN;//右端点最大值
while(n--){
int x,y;
cin>>x>>y;
a[y].push_back(x);//储存每个右端点对应的左端点
maxn=max(maxn,y);
}
for(int i=0;i<=maxn;i++){
//初始化
if(i==0){
dp[i]=0;
}
else dp[i]=dp[i-1];
if(i!=0){
//遍历左端点(如果没有左端点不会进此循环)
for(auto j:a[i]){
if(j!=0){
dp[i]=max(dp[i],dp[j-1]+(i-j+1));//dp方程
}
else dp[i]=max(dp[i],i-j+1);//当j为0时dp[j-1]会越界,要特殊处理
}
}
}
cout<<dp[maxn];
return 0;
}