1. 程式人生 > >hdu 6180貪心

hdu 6180貪心

bsp urn end 時間排序 有一個 判斷 對比 efi 起點

題意:有m個工程,一臺機器在同一時間只能運行一個工程,告訴你每個工程的起始時間和結束時間,求出最少要多少個機器以及最小的機器總運行時間(機器開始了就不能停了,知道用完該臺機器才停止)。

題解:由於這裏可以使用多臺機器,那麽我們用起點排序也能夠得到最小的k。(對比了下典型的區間調度問題,那個問題由於只有一臺機器,所以必須用結束時間排序——盡早結束可以有更多的機會接觸更多的時間區間)。然後題目要求最小的工作時間,這裏我們只要保證一臺機器運行的兩個工程之間的時間間隔最小就可以了,也是一個貪心。一開始我用一個隊列來維護機器的結束但是這是不行的,因為在判斷是否需要新引入一臺機器的時候,我們希望隊列的首位為結束時間最早的機器;而當我們計算時間的時候,我們希望能有一個符合條件的結束時間最晚的機器來繼續現在的工程。所以我們需要兩個隊列來維護,一個工作隊列,一個空閑隊列。

ac代碼:

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <functional>
#define
N 100010 #define LL __int64 #define inf 0x3f3f3f3f using namespace std; const LL mod = 1e9 + 7; struct node { LL st, en; }thing[N]; bool cmp1(node a, node b) { if (a.st == b.st) { return a.en < b.en; } return a.st < b.st; } int main() { cin.sync_with_stdio(false); int
T; int n; cin >> T; while (T--) { cin >> n; priority_queue<LL>p;//空閑集合 priority_queue<LL, vector<LL>, greater<LL> >q;//工作集合 for (int i = 0; i < n; i++) { cin >> thing[i].st >> thing[i].en; } LL ans = 0, sum = 0; sort(thing, thing + n, cmp1); for (int i = 0; i < n; i++) { node now = thing[i]; while ((!q.empty()) && q.top() <= now.st) { p.push(q.top()); q.pop(); } if (!p.empty()) { int num = p.top(); p.pop(); sum += now.en - num; q.push(now.en); } else { ans++; sum += now.en - now.st; q.push(now.en); } } cout << ans << " " << sum << endl; } return 0; }

hdu 6180貪心