【差分】會場安排問題
很久很久以前的東西了。。
那時候是弱菜中的弱菜(現在是弱菜),這篇文章我也不改什麼。。
«問題描述:假設要在足夠多的會場裡安排一批活動,並希望使用盡可能少的會場。設計一個有效的貪心演算法進行安排。(這個問題實際上是著名的圖著色問題。若將每一個活動作為圖的一個頂點,不相容活動間用邊相連。使相鄰頂點著有不同顏色的最小著色數,相應於要找的最小
會場數。)
«程式設計任務:對於給定的k個待安排的活動,程式設計計算使用最少會場的時間表。«資料輸入:由檔案input.txt給出輸入資料。第一行有1 個正整數k,表示有k個待安排的活動。接下來的k行中,每行有2個正整數,分別表示k個待安排的活動開始時間和結束時間。時間以0 點開始的分鐘計。«結果輸出:將程式設計計算出的最少會場數輸出到檔案output.txt。輸入檔案示例 輸出檔案示例input.txt output.txt5 31 2312 2825 3527 80
36 50
(CJMXHLXW)
這道題是我們考試的一道題,當時我看到就懵逼,考試考的是貪心分治,可是我考試的時候做別的難題去了,越做越煩,做這題時貪心都沒貪出來,結果那次考試爆0,尷尬了。
考試完題目總是要講解的嘛,黃司機A掉了這道題,這道題先是他上去講解貪心演算法,時間複雜度為O(n^2)。
第二天,wen大神又來為我們講解了某種高階演算法——好像提到了差分陣列,我居然聽懂了。而且還心血來潮,寫了個題解。=_=
首先搞懂這個“差分陣列”,我們用到的主要功能就是在某個集合裡,在[L,R]這個區間內,把每個數都加上k,用我們普通的演算法肯定是for一遍,這樣如果有n個數,要m次操作,那麼時間複雜度就是O(mn),而這道題的範圍n有10^8,m有10^4,顯然這是不行的。這裡wen大神介紹了一種新的資料結構——差分陣列。把[L,R]區間裡都加上k,只需要把a[L]加上k,再把a[R+1]減去k就行了,當時聽了也不懂,這樣後求L~R區間的和不是隻加了1個k嗎。原來求和的sum[i]加到a[L]時,值為k,加了a[R+1]後,又變為0,我們就可以理解為[L,R]區間裡都加了k。還有這種操作?
好了,上程式碼
#include <iostream> #include <map> using namespace std; int a[100010],b[100010],c[100010],d[100010],n,now,sum,Max; map<int,int>e; int main(){ freopen("sche.in","r",stdin); freopen("sche.out","w",stdout); cin>>n; for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); c[2*i-1]=a[i]; c[2*i]=b[i]; } sort(c+1,c+2*n+1); for(int i=1;i<=2*n;i++) if(!e[c[i]]) e[c[i]]=++now; for(int i=1;i<=n;i++) d[e[a[i]]]++, d[e[b[i]]]--; for(int i=1;i<=now+1;i++) sum+=d[i], Max=max(Max,sum); cout<<Max; fclose(stdin); fclose(stdout); //system("pause"); return 0; }