1. 程式人生 > >sincerit 會場安排問題(區間選點 貪心)

sincerit 會場安排問題(區間選點 貪心)

14 會場安排問題
時間限制:3000 ms | 記憶體限制:65535 KB
難度:4
描述
學校的小禮堂每天都會有許多活動,有時間這些活動的計劃時間會發生衝突,需要選擇出一些活動進行舉辦。小劉的工作就是安排學校小禮堂的活動,每個時間最多安排一個活動。現在小劉有一些活動計劃的時間表,他想盡可能的安排更多的活動,請問他該如何安排。
輸入
第一行是一個整型數m(m<100)表示共有m組測試資料。
每組測試資料的第一行是一個整數n(1<n<10000)表示該測試資料共有n個活動。
隨後的n行,每行有兩個正整數Bi,Ei(0<=Bi,Ei<10000),分別表示第i個活動的起始與結束時間(Bi<=Ei)
輸出
對於每一組輸入,輸出最多能夠安排的活動數量。
每組的輸出佔一行
樣例輸入
2
2
1 10
10 11
3
1 10
10 11
11 20
樣例輸出
1
2
提示
注意:如果上一個活動在t時間結束,下一個活動最早應該在t+1時間開始

每一場活動的開始,必須在上一場活動結束後,給出n個活動。因為時間是個天然的順序,並且我們判斷當前場次活動是否能開始的依據是上一場活動是否已經結束。所以我們按照活動的結束時間從小到大排列,如果結束時間相同,則開始時間晚的排在前面,因為佔用的區間小。已經排好序,那麼選取的第一個區間應該是哪一個才能求出最優解呢?

第一個區間必選。第一個區間結束的時間最早,之後的區間1.結束時間和第一個區間相同,開始時間比第一個區間早,因為應該選擇儘量小的區間,所以這種情況選擇第一個區間。2.開始時間相同,結束時間比第一個區間晚。3.開始時間比第一個區間早,結束時間比第一個時間晚。 其實這3種情況都是包含第一個區間,應選擇最小區間,捨去大區間,因此第一個區間是必選的,那麼之後就用一個變數記錄上一個活動的結束時間,和當前活動的開始時間進行比較,即可獲得最優解
所以以後這樣的題目,排好序之後,第一個區間是必選的,就從第一個開始比較

#include<stdio.h>
#include<string.h>
#include<stack>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct Time
{
    int start;
    int over;
} a[10001];
int cmp(Time x,Time y)
{
    return x.over<y.over;//根據結束時間升序排列
}
int main()
{
    int
m; scanf("%d",&m); while(m--) { int n; scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&a[i].start,&a[i].over); sort(a,a+n,cmp); int sum=1;//總數是從1開始的,因為題設 int flag=a[0].over;//設定最小結束時間 for(int i=1; i<n; i++) if(a[i].start>flag)//如果當前開始時間在標記的結束時間之後,表示可以進行這個活動 { flag=a[i].over; sum++; } printf("%d\n",sum); } return 0; }