做法:线段树优化dp
思路:
dp[i]表示覆盖[1,i]需要的最少区间数。然后用线段树更新取最小值。
dp[t]=min(dp[t],min(dp[s]~dp[t])+1)
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=5e4+10,INF=0x3f3f3f3f;
int n,m;
int dp[N<<2];
int query(int u,int l,int r,int x,int y){
if(l>=x&&r<=y) return dp[u];
int mid=(l+r)>>1,sum=INF;
if(x<=mid) sum=query(u<<1,l,mid,x,y);
if(y>=mid+1) sum=min(sum,query(u<<1|1,mid+1,r,x,y));
return sum;
}
void modify(int u,int l,int r,int x,int y){
if(l==r) dp[u]=min(dp[u],y);
else{
int mid=(l+r)>>1;
if(x<=mid) modify(u<<1,l,mid,x,y);
else if(x>=mid+1) modify(u<<1|1,mid+1,r,x,y);
dp[u]=min(dp[u<<1],dp[u<<1|1]);
}
}
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
memset(dp,INF,sizeof dp);
cin>>n>>m;
modify(1,1,n,1,0);
for(int i=0;i<m;i++){
int s,t;cin>>s>>t;
int temp=query(1,1,n,s,t)+1;
modify(1,1,n,t,temp);
}
cout<<query(1,1,n,n,n)<<"\n";
return 0;
}
京公网安备 11010502036488号