P1668 [USACO04DEC] Cleaning Shifts S 题解
题面大意
给你一个
分析
首先,因为因为它要令几个区间的并集为
所以,我们考虑贪心求覆盖当前区间
当
显然,当前区间并与该选定区间合并等价于令当前区间并的最大右端点与该选定区间右端点取最大值。
所以,我们直接把当前区间并的最大右端点赋值为该选定区间右端点取最大值。
而,若赋值后区间并的最大右端点仍小于
代码
#include<bits/stdc++.h>
using namespace std;
constexpr int N=1e6+5;
int n,t,la,ma[N],maa,ans;
struct node{
int s,e;
}a[N];//给定区间
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>t;la=1;
for(int i=1;i<=n;i++) cin>>a[i].s>>a[i].e,ma[a[i].s]=max(ma[a[i].s],a[i].e);//ma[i]:以i为左端点区间的最大右端点
for(int i=1;i<=t;i++){
if(la<i) cout<<-1,exit(0);//若无解,输出-1
maa=max(maa,ma[i]);//求选定区间右端点
if(la==i) la=maa+1,ans++;//提前一步赋值为选定区间右端点,la是最大右端点+1
}
if(la<=t) cout<<-1,exit(0);//同上
cout<<ans;
return 0;
}
该算法不用快排,所以不带