Cleaning Shifts
Descriptions:
原文是English,我这就直接上Chinese了,想看原文的点一下链接哦
大表哥分配 N (1 <= N <= 25,000) 只中的一些奶牛在牛棚附近做些清洁。 他总是要让至少一只牛做清洁。他把一天分成T段(1 <= T <= 1,000,000), 第一段是1,最后一段是T
每只奶牛只在一些时间段有空。奶牛如果选择某一段时间,则必须完成整段时间的工作
你的任务是帮助FJ安排一些奶牛,使每段时间至少有一只奶牛被安排来做这件事。并且奶牛数应尽可能小。如果不可能办到,输出-1
每只奶牛只在一些时间段有空。奶牛如果选择某一段时间,则必须完成整段时间的工作
你的任务是帮助FJ安排一些奶牛,使每段时间至少有一只奶牛被安排来做这件事。并且奶牛数应尽可能小。如果不可能办到,输出-1
Input
注意,输入包含多组测试数据,请处理到文件结束
* 第一行:N和T
* 第二行至N+1行: 每一行包括奶牛能工作的开始和结束时间。闭区间。
* 第一行:N和T
* 第二行至N+1行: 每一行包括奶牛能工作的开始和结束时间。闭区间。
Output
*每组数据一行,输出完成清洁所需最少的奶牛数,如果不可能办到,输出-1
Sample Input
3 10 1 7 3 6 6 10
Sample Output
2
题目链接:
https://vjudge.net/problem/POJ-2376
给定N个小区间以及区间起点终点,求能用它们覆盖区间[1,T]的最小组合。
贪心策略是从左往右,尽量选择长度最大的区间。
首先对所有奶牛排序,按照开始时间排序。
然后更新起点=终点+1,搜索剩下的奶牛中能够覆盖这个起点同时终点最远的那一头,更新终点。
AC代码;
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #include <sstream> #define mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define ME0(x) memset(x,0,sizeof(x)) using namespace std; int N,T; struct cow { int s;//开始时间start的缩写 int e;//结束时间end的缩写 int no; bool operator<(const cow &c)const//按开始时间从大到小排序 { return s<c.s; } }; int main() { while(cin>>N>>T) { cow cows[25010];//在这里设置数组就不用每次都重置数组了 for(int i=0; i<N; ++i) cin>>cows[i].s>>cows[i].e; sort(cows,cows+N);//排序 // for(int i=0; i<N; i++) // cout<<cows[i].s<<" "<<cows[i].e<<endl; int over=0;//结束时间 int pos=0;//位置 int sum=0;//一共几头牛 while(over<T) { int start=over+1;//每次的开始时间都是上一次的结束时间+1 // cout<<"***"<<start<<endl; for(int i=pos; i<N; ++i) { if(cows[i].s<=start)//能够覆盖起始点 { if(cows[i].e>over) over=max(over,cows[i].e);//将结束时间延长到最远 } else { //不能覆盖起点,说明上一头牛的终点就是最远点,需要换一头牛了 // cout<<cows[i].s<<" "<<cows[i].e<<endl; pos=i; break; } } // 没找到这样的牛,失败 if(start>over) { cout<<-1<<endl; break; } //找到了,+1 else ++sum; } if(over>=T)//正常跳出循环,输出sum即可 cout<<sum<<endl; } }