问题主题:区间调度问题
问题描述:
有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。
限制条件:
1<=n<=100000
1<=si<=ti,=109
样例:
输入
n=5
s={1,2,4,6,8}
T={3,5,7,9,10}
输出
3(选择工作1, 3, 5)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int MAX_N = 1e5 + 3; 7 8 int N,S[MAX_N],T[MAX_N]; 9 10 pair<int,int> itv[MAX_N]; 11 12 void solve() 13 { 14 for(int i=0;i<N;++i) 15 { 16 // 注意存储顺序 17 // sort先按第一中间遍历排序,再按第二中间变量排序 18 // 而我们贪心工作的最早结束时间,这一最早结束时间是否有对应满足的开始时间 19 itv[i].first=T[i]; 20 itv[i].second=S[i]; 21 } 22 sort(itv,itv+N); 23 24 for(int i=0;i<N;++i) 25 { 26 printf("%d %d ",itv[i].first,itv[i].second); 27 } 28 29 int ans=0,t=0; 30 for(int i=0;i<N;++i) 31 { 32 // 按结束时间升序遍历 33 // 如果可行区间起点t,小于当前开始时间, 34 // 满足条件 35 if(t<itv[i].second) 36 { 37 ans++; 38 // 更新当前结束时间,为可行区间的起点(左端点) 39 t=itv[i].first; 40 } 41 } 42 //cout<<ans<<endl; 43 printf("%d ",ans); 44 } 45 46 int main() 47 { 48 scanf("%d",&N); 49 for(int i=0;i<N;++i) 50 { 51 scanf("%d",&S[i]); 52 } 53 for(int i=0;i<N;++i) 54 { 55 scanf("%d",&T[i]); 56 } 57 solve(); 58 return 0; 59 } 60 61 /* 62 5 63 1 2 4 6 8 64 3 5 7 9 10 65 7 66 1 2 1 2 4 6 8 67 4 3 3 5 7 9 10 68 */