假設要在足夠多的會場里安排一批活動,並希望使用盡可能少的會場。設計一個有效的 貪心算法進行安排。(這個問題實際上是著名的圖着色問題。若將每一個活動作為圖的一個 頂點,不相容活動間用邊相連。使相鄰頂點着有不同顏色的最小着色數,相應於要找的最小 會場數。)
輸入格式:
第一行有 1 個正整數k,表示有 k個待安排的活動。 接下來的 k行中,每行有 2個正整數,分別表示 k個待安排的活動開始時間和結束時間。時間 以 0 點開始的分鍾計。
輸出格式:
輸出最少會場數。
輸入樣例:
5
1 23
12 28
25 35
27 80
36 50
輸出樣例:
在這里給出相應的輸出。例如:
3
解法一:貪心法
貪心法也可以得到最優解,但是不是以最早結束時間排序,而是以最早開始時間排序,理由不知
#include<iostream>
#include<algorithm>
using namespace std;
struct activity
{
int start;
int end;
int visited=0;
}aty[1010];
bool cmp(activity a,activity b){
if(a.start==b.start){
return a.end<b.end;
}
return a.start<b.start;
}
int main(){
int k;
cin>>k;
for(int i=0;i<k;i++){
cin>>aty[i].start>>aty[i].end;
}
sort(aty,aty+k,cmp);
int site=0;
for(int i=0;i<k;i++){
if(!aty[i].visited){
site++;
int endtime=aty[i].end;
for(int j=i+1;j<k;j++){
if(aty[j].start >= endtime && !aty[j].visited){
aty[j].visited=1;
endtime=aty[j].end;
}
}
}
}
cout<<site;
return 0;
}
解法二
把開始時間和結束時間都排序,我在這里理解是,會場變得“無序”了,由於開始時間和結束時間都是按遞增的順序排序,所以只要下一個活動的開始時間比當前最晚的結束時間還要晚,那么就不需要增加會場,而當開始時間比當前最晚的結束時間要早,那么肯定要再加一個會場才能安排。而最晚的開始時間不變,這是因為活動的開始時間和結束時間是分開考慮的,還沒“輪到考慮新添加的活動的時間”。
#include<iostream>
#include<algorithm>
using namespace std;
int a[100], b[100];
void shu(int k, int start[], int end[]) {
int count = 0;
int j = 0;
for (int i = 0; i < k; i++) {
if (start[i] < end[j]) {
count++; //增加一個會場
}
else {
j++; //可以使用前面的會場
}
}
cout << count;
}
int main() {
int k;
cin >> k;
for (int i = 0; i < k; i++) {
cin >> a[i] >> b[i];
}
sort(a, a + k); //先排好序
sort(b, b + k);
shu(k, a, b);
}
