POJ 3190 Stall Reservations
问题抽象成数学概念就是:给你n条线段,问最少需要分成几组,使得每组中的线段互不相交
贪心:
把线段按左端点排序,对于每一组,我们用一个变量t记录这组里面的线段中的最大的右端点
对于每一条线段,我们找到t最大且<左端点的那组,把这条线段加进该组,同时更新该组的t
这里可以用set中的lower_bound()实现
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define pb(a) push_back(a) #define INF 0x1f1f1f1f #define lson idx<<1,l,mid #define rson idx<<1|1,mid+1,r #define PI 3.1415926535898 void debug() { #ifdef ONLINE_JUDGE #else freopen("d:\\in.txt","r",stdin); // freopen("d:\\out1.txt","w",stdout); #endif } char getch() { char ch; while((ch=getchar())!=EOF) { if(ch!=' '&&ch!='\n')return ch; } return EOF; } struct cow //牛 { int l,r,id; bool operator <(cow a)const { if(l!=a.l) return l<a.l; else return r<a.r; } }x[50010]; struct stall //stall { int t,id; bool operator <(stall a)const { return t<a.t; } }; int ans[50010]; int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d%d",&x[i].l,&x[i].r); x[i].id=i; } multiset<stall> s; sort(x+1,x+1+n); int num=0;// 记录组数 for(int i=1;i<=n;i++) { int val=x[i].l; multiset<stall>::iterator it; it=s.lower_bound((stall){val,1}); //lower_bound找到的是大于等于val的第一个数,最大且小于val的就是前面一个 if(it==s.begin()) { //如果找不到,新开一组 s.insert((stall){x[i].r,++num}); ans[x[i].id]=num; }else { //存在,加进去 it--; stall k=*it; k.t=x[i].r; ans[x[i].id]=k.id; s.erase(it); s.insert(k); } } printf("%d\n",num); for(int i=1;i<=n;i++) printf("%d\n",ans[i]); return 0; } return 0; }
隔了几个月再遇到这道题,发现没必要找t最大的那组,只要小于左端点就行了。
用优先队列可以比较方便
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; #define pb(a) push(a) #define INF 0x1f1f1f1f #define lson idx<<1,l,mid #define rson idx<<1|1,mid+1,r #define PI 3.1415926535898 template<class T> T min(const T& a,const T& b,const T& c) { return min(min(a,b),min(a,c)); } template<class T> T max(const T& a,const T& b,const T& c) { return max(max(a,b),max(a,c)); } void debug() { #ifdef ONLINE_JUDGE #else freopen("in.txt","r",stdin); //freopen("d:\\out1.txt","w",stdout); #endif } int getch() { int ch; while((ch=getchar())!=EOF) { if(ch!=' '&&ch!='\n')return ch; } return EOF; } struct cow { int first,second,id; bool operator < (const cow &ant) const { if(first!=ant.first) return first<ant.first; else return second<ant.second; } }; const int maxn = 50005; cow da[maxn]; struct Node { int x,id; bool operator < (const Node &ant) const { return x>ant.x; } }; int res[maxn]; int main() { int n; std::ios::sync_with_stdio(false); while(cin>>n) { for(int i=0;i<n;i++) { cin>>da[i].first>>da[i].second; da[i].id=i; } sort(da,da+n); priority_queue<Node> q; int scnt=0; for(int i=0;i<n;i++) { int l=da[i].first,r=da[i].second; if(!q.empty()&&q.top().x<l) { Node k=q.top();q.pop(); k.x=r; q.push(k); res[da[i].id]=k.id; }else { q.push((Node){r,++scnt}); res[da[i].id]=scnt; } } cout<<scnt<<endl; for(int i=0;i<n;i++) cout<<res[i]<<endl; } return 0; }