【POJ - 2376】Cleaning Shifts (贪心)
題干:
Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores around the barn. He always wants to have one cow working on cleaning things up and has divided the day into T shifts (1 <= T <= 1,000,000), the first being shift 1 and the last being shift T.?
Each cow is only available at some interval of times during the day for work on cleaning. Any cow that is selected for cleaning duty will work for the entirety of her interval.?
Your job is to help Farmer John assign some cows to shifts so that (i) every shift has at least one cow assigned to it, and (ii) as few cows as possible are involved in cleaning. If it is not possible to assign a cow to each shift, print -1.
Input
* Line 1: Two space-separated integers: N and T?
* Lines 2..N+1: Each line contains the start and end times of the interval during which a cow can work. A cow starts work at the start time and finishes after the end time.
Output
* Line 1: The minimum number of cows Farmer John needs to hire or -1 if it is not possible to assign a cow to each shift.
Sample Input
3 10 1 7 3 6 6 10Sample Output
2Hint
This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.?
INPUT DETAILS:?
There are 3 cows and 10 shifts. Cow #1 can work shifts 1..7, cow #2 can work shifts 3..6, and cow #3 can work shifts 6..10.?
OUTPUT DETAILS:?
By selecting cows #1 and #3, all shifts are covered. There is no way to cover all the shifts using fewer than 2 cows.
題目大意:
? ??農夫有N頭?!,F在他想讓一些牛去做家務。然后他把一天分成T個時間點,也就是一天的時間點是區間[1,T]。他想要任何一個時間點都有牛在做家務?,F在給出每頭牛的工作時間,問你能否用最少的牛滿足他的要求,即用最少的時間段覆蓋掉這一天([1,T])。如果不能滿足則輸出-1,否則輸出最少的牛數量。
分析:貪心題。題目意思很明顯是求最少的區間覆蓋掉大區間。先對這些時間段排好序,這個排序應該是沒什么問題的。然后呢,第一頭牛肯定要選,就從這頭牛開始,選取下一頭牛。下一頭牛怎么選取呢?即在滿足條件的牛里面(注意:滿足條件的牛是只要開始工作時間 start>=cow[0].y+1 即可),選取右邊界值最大的那個,因為這樣子能夠覆蓋掉最多的時間段。以此類推,故貪心法求之。
解題報告:
? ? ? ? ? ?代碼太多,已經分不清了。
AC代碼1:
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; struct co{int beg;int end; }; bool cmp(co a,co b){if(a.beg==b.beg) {return a.end<b.end;}return a.beg<b.beg; } int main() {int n,t;cin >> n>> t;co cow[25005];//若定義在全局變量 即 struct中 那么會有自動補全功能存在 如果這樣定義 則沒有 for(int i=1;i<=n;i++){scanf("%d%d",&cow[i].beg,&cow[i].end);}int cur=0;int low;int pos=1;int ans=0;sort(cow+1,cow+n+1,cmp);while(cur<=t){ //行嗎 low=cur+1;int i; // for(i=pos;cow[i].beg<=low&&cow[i].end>=low;i++){//這樣寫不可以!!只能i<=n 然后再for里面用if來判斷是否結束虛幻 或者繼續循環 這樣更好一些 // cur=max(cur,cow[i].end); // } // pos=i;for(i=pos;i<=n;i++){if(cow[i].beg<=low&&cow[i].end>=low){cur=max(cur,cow[i].end);}else if (cow[i].beg>low) {pos=i;break;} }if(low>cur) {break;}else {++ans;}}if(cur>=t) cout << ans << endl;else cout << -1 << endl;return 0 ;}?
?
AC代碼2:
#include<iostream> #include<cstdio> #include<algorithm>const int MAX= 25000 + 5; typedef long long ll; struct co{int start;int end; } cow[MAX]; //ll a[] bool cmp( const co & a1,const co & a2){if(a1.start==a2.start) {return a1.end > a2.end;}return a1.start<a2.start; } using namespace std; int main() {int n,t;int cur=0;scanf("%d%d",&n,&t);int sum=0;for(int i=0;i<n;i++){scanf("%d%d",&cow[i].start,&cow[i].end);} sort(cow,cow+n,cmp);int po=0;//從第po頭牛開始找 // int maxx=0;//其實就是cur while(cur<t){//如果當前的最大值還是小于t的話 //int flag=0;int min=cur+1;for(int i=po;i<n;i++) {if(cow[i].start<=min&&cow[i].end>=min){//不能用cur也不能cur+1 !! 因為cur不能變 但是這樣cur就變了! // flag=1;cur=max(cur,cow[i].end);//maxx=max(maxx,cow[i].end);} else if(cow[i].start>min){// flag=1;po=i;//下一次從第i個開始找break; }}// if(flag==0) break;if(min>cur) break;else ++sum;}if(cur>=t) cout << sum << endl;else cout << -1<<endl;return 0 ;}AC代碼3:
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; struct A { int left,right; }; int cmp(const A &a,const A &b) { if(a.left==b.left) return a.right<b.right; return a.left <b.left; } int main() { A a[25005],b[25005]; int m,n,c; scanf("%d%d",&n,&c);for(int i=0; i<n; i++) { scanf("%d%d",&a[i].left,&a[i].right); } sort(a,a+n,cmp); /*for(int i=0;i<n;i++) cout << a[i].left <<" "<< a[i].right<<endl;*/ int max=0; int sum=0; int top=0; while(max<c) { int min=max+1; for(int i=top; i<n; i++) if(a[i].left<=min&&a[i].right>=min) max=max>a[i].right?max:a[i].right; else if(a[i].left>min) { top=i; break; } if(min>max) break; else sum++; } if(max>=c) cout << sum <<endl; else cout << "-1\n"; return 0; }?AC代碼4:
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; struct A { int left,right; }; int cmp(const A &a,const A &b) { if(a.left==b.left) return a.right<b.right; return a.left <b.left; } int main() { A a[25005],b[25005]; int m,n,c; scanf("%d%d",&n,&c);for(int i=0; i<n; i++) { scanf("%d%d",&a[i].left,&a[i].right); } sort(a,a+n,cmp); /*for(int i=0;i<n;i++) cout << a[i].left <<" "<< a[i].right<<endl;*/ int max=0; int sum=0; int top=0; while(max<c) { int min=max+1; for(int i=top; i<n; i++) if(a[i].left<=min&&a[i].right>=min) max=max>a[i].right?max:a[i].right; else if(a[i].left>min) { top=i; break; } if(min>max) break; else sum++; } if(max>=c) cout << sum <<endl; else cout << "-1\n"; return 0; }?
總結
以上是生活随笔為你收集整理的【POJ - 2376】Cleaning Shifts (贪心)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新一代iPad mini曝光:供应量称配
- 下一篇: 曝6.7英寸版iPhone 14要改名: