1. 程式人生 > >貪心演算法:活動安排問題

貪心演算法:活動安排問題

問題描述:
現在給你一個會場,有許社團需要在這個會場上活動,
已知各個社團在這個會場上活動的時間(起始時間和終止時間)
要求出來怎麼安排
能夠使得這個教室z在這一天之內接待儘可能多的社團

  •  解題思路與演算法思想

     已經知道我們有n個活動需要安排
     	不妨考慮我們需要首先安排哪個活動
              如果這n個活動的開始時間分別為a1-an
     		  結束時間分別為b1-bn
     			那麼對於我們要安排的第一個活動而言(假設這個活動是第i個)
     				無論他的開始時間是多少
     				**他佔用的時間都是bi**
     這是由於雖然她只佔用了ai-bi的時間
     	但是其實第一個活動,那麼從0 - ai時間段裡註定沒有活動
     在選取好了第一個活動之後 		
     	我們需要選取第二個活動 
     	那麼通過將和第一次活動重合的全部活動去掉的方式
    

    我們可以將這個問題轉化成選取第一個活動的問題

  • 程式模型的建

  • 那麼可以通過各個社團的結束時間對各個社團進行排序

  • 使得結束時間最早的以一些社團位於最前面
    -利用貪心的思想

    				每一都選取結束時間最靠前的哪一個
    				同時去除其他與這個被選擇社團時間衝突的社團
    				再進行下一次比較
    
  • 資料結構的選用

  •  利用陣列去儲存各個社團的開始和終止時間
    
  •  程式設計流程

  •  輸入資料
    
  •  進行排序
    
  •  得到結果
    
  • 程式設計偽碼演算法

     get things stored in a 
     sort a
     while(i<a,size()) 
     {
     	if(現在第第一位的開始時間等於大於上一個被選中社團的終止時間)
     	{
     		計數器+1 ;
     	}
     	i++ ;
     }
    

 源程式編碼清單

#include<iostream>
#include<utility>
#include<vector>
#include<algorithm>
using namespace std ;

bool comp(pair<int ,int >a ,pair<int ,int>b) ;

int main(void)
{
	vector< pair<int, int> > b ;
	int n  ;
	scanf("%d",&n) ;
	b.resize(n) ; 
	for(int i = 0 ;i<n ;i++)
	{
		int tem  ;
		scanf("%d",&tem) ;
		b[i].first = tem ;
		scanf("%d",&tem) ;
		b[i].second = tem ;
	}
	
	sort(b.begin(),b.end(),comp) ;
	int end ;
	end =b[0].second;
	
	int cnt = 1 ;
	
	for(int i = 0 ;i<b.size() ;i++)
	{
		if(b[i].first >= end)
		{
			end = b[i].second ;
			cnt++ ;
		}
	}
	
	
	printf("%d ",cnt) ;
	
	return 0 ;
	
	
	
	
	
}

bool comp(pair<int ,int >a ,pair<int ,int>b)
{
	if(a.second<b.second)
	{
		return true ;
	}
	else
	{
		return false ;
	}
}

 
  •  程式輸入、輸出

     輸入:
     		5
     		1 2 3 4 5 6 7 8 9 10
     輸出:5
    

輸入輸出檔案或程式執行結果截圖

  • 時間與空間複雜度分析

     時間複雜度:
     	nlogn+n
    

 程式使用說明
 總結與完善