【BZOJ1572】【usaco 2009 open】工作安排job
【問題描述】
? ??Farmer John 有太多的工作要做啊!!!!!!!!為了讓農場高效運轉,他必須靠他的工作賺錢,每項工作花一個單位時間。 他的工作日從0時刻開始,有1000000000個單位時間(!)。在任一時刻,他都可以選擇編號1~N的N(1 <= N <= 100000)項工作中的任意一項工作來完成。 因為他在每個單位時間里只能做一個工作,而每項工作又有一個截止日期,所以他很難有時間完成所有N個工作,雖然還是有可能。 對于第i個工作,有一個截止時間D_i(1 <= D_i <= 1000000000),如果他可以完成這個工作,那么他可以獲利P_i( 1<=P_i<=1000000000 ). 在給定的工作利潤和截止時間下,FJ能夠獲得的利潤最大為多少呢?答案可能會超過32位整型。
【分析】
? ? 貪心。先將工作按截止時間排序。添加一個時間在0時間,且截止時間為0利潤為0,維護一個時間和堆。初始狀態下,時間設為極大值。只要當前時間大于當前事件的截止時間,便取出堆頂,利潤增加,時間減一。再讓時間等于當前事件的截止時間,把當前事件的利潤加入堆。
? ?詳見代碼。
? ? 順便一提,c++可以直接用priority_queue做大根堆,就省打了很多。
【代碼】
? ??
//bzoj1572(lydsy) //usaco 09 open #include <iostream> #include <cstdio> #include <queue> #include <algorithm> using namespace std;priority_queue<long long, vector<long long> >q;struct apair {int d;int p; }a[100050];bool operator < (const apair& lhs,const apair& rhs) {return lhs.d < rhs.d;}int n; int main() {freopen("job.in","r",stdin);freopen("job.out","w",stdout);cin >> n;for (int i = 1; i <= n; i ++)scanf("%d %d",&a[i].d,&a[i].p);a[++n].d = 0;a[n].p = 0;sort(a + 1,a + n +1);long long ans = 0;long long now = 1000000000;for (int i = n; i > 0; i--){while (now > a[i].d && q.size() > 0){now--;ans += q.top();q.pop();}now = a[i].d;q.push(a[i].p);}cout << ans << endl;fclose(stdin);fclose(stdout); }轉載于:https://www.cnblogs.com/N-C-Derek/archive/2012/07/11/usaco_09_open_job.html
總結
以上是生活随笔為你收集整理的【BZOJ1572】【usaco 2009 open】工作安排job的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算矩阵连乘积(动态规划)
- 下一篇: PHP 的时间格式