LA 4254 Processor 处理器 【二分 贪心 优先队列】
題目鏈接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21663
二分:
最大值最小的問(wèn)題通過(guò)二分來(lái)求解。對(duì)處理器速度進(jìn)行二分之后,問(wèn)題就轉(zhuǎn)化成了對(duì)于給定的處理速度,問(wèn)處理器是否可以將這些問(wèn)題處理完。
貪心:
一個(gè)貪心的思路就是每個(gè)時(shí)刻應(yīng)該盡量 做可以做的任務(wù)中,結(jié)束時(shí)間最早的那個(gè),這樣最起碼不會(huì)使結(jié)果更糟。這樣就可以枚舉每個(gè)單位時(shí)間,然后去找可以做的并且結(jié)束時(shí)間最早的那個(gè)去做,直到用完這一單位時(shí)間或者無(wú)任務(wù)可做為止。最后如果發(fā)現(xiàn)哪個(gè)任務(wù)還沒(méi)做完,就說(shuō)明在這個(gè)給定的處理速度下,處理器是不能完成所有任務(wù)的。
優(yōu)先隊(duì)列:
總體的思路就是,將所有任務(wù)按照開始時(shí)間排序,二分枚舉處理器的速度,然后對(duì)每個(gè)速度進(jìn)行判斷。按照任務(wù)開始時(shí)間依次加入優(yōu)先隊(duì)列,隊(duì)列優(yōu)先級(jí)是結(jié)束時(shí)間早的優(yōu)先。最后就能判斷該速度是否能夠執(zhí)行完所有任務(wù)。
?
?
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<string> 7 #include<vector> 8 #include<set> 9 #include<queue> 10 #include<map> 11 #include<stack> 12 using namespace std; 13 #define clr(c) memset(c, 0, sizeof(c)); 14 const int INF = 0x3f3f3f3f; 15 typedef long long ll; 16 typedef unsigned long long ull; 17 typedef struct Job{ 18 int l, r, w; 19 bool operator < (const Job& j) const{ // 用于優(yōu)先隊(duì)列內(nèi)部排序 20 return r > j.r; // r大的優(yōu)先級(jí)低,優(yōu)先隊(duì)列先輸出優(yōu)先級(jí)大的成員 21 } 22 bool operator > (const Job& j) const{ 23 return j < *this; 24 } 25 }Job; 26 27 bool cmp(Job j1, Job j2){ // 用于sort函數(shù) 28 return j1.l < j2.l; // 當(dāng)返回true時(shí)表示比較結(jié)果符合要求,不需要交換位置 29 } 30 const int MAXL = 10005; 31 Job J[MAXL]; 32 int T, n, Begin, End, MaxS, l, r, mid, ans; 33 bool Ok(int speed){ 34 priority_queue<Job> Q; 35 int pos = 0; 36 for(int i = Begin; i <= End; i++){ 37 int time = speed; 38 while(J[pos].l < i && pos < n) Q.push(J[pos++]); 39 while(!Q.empty() && time != 0){ 40 Job Jtemp = Q.top(); 41 Q.pop(); 42 if(Jtemp.r < i) return false; // 此時(shí)已經(jīng)過(guò)了任務(wù)的執(zhí)行期限, 說(shuō)明此速度不能完成執(zhí)行任務(wù) 43 if(Jtemp.w > time){ 44 Jtemp.w -= time; 45 time = 0; 46 Q.push(Jtemp); // 執(zhí)行一部分任務(wù),此任務(wù)未完成部分重新入隊(duì) 47 } 48 else time -= Jtemp.w; // 此任務(wù)執(zhí)行完畢, 利用剩余時(shí)間執(zhí)行下一任務(wù) 49 } 50 } 51 if(Q.empty()) return true; 52 else return false; 53 } 54 55 int main(){ 56 scanf("%d", &T); 57 while(T--){ 58 Begin = INF, End = 0, MaxS = 0; 59 scanf("%d", &n); 60 for(int i = 0; i < n; i++){ 61 scanf("%d%d%d", &J[i].l, &J[i].r, &J[i].w); 62 Begin = min(Begin, J[i].l); // 所有任務(wù)的最早開始時(shí)間 63 End = max(End, J[i].r); // 所有任務(wù)的最晚結(jié)束時(shí)間 64 MaxS += J[i].w; // 最大速度:在1個(gè)單位時(shí)間內(nèi)所有任務(wù)都要完成,則速度必須大于等于所有任務(wù)的工作量的和 65 } 66 sort(J, J+n, cmp); 67 l = 0, r = MaxS, ans = INF; 68 while(l <= r){ // 二分 69 mid = (l + r) >> 1; // (l + r) / 2; 70 if(Ok(mid)){ 71 r = mid -1; // 尋找所有符合要求的速度里面最小的那個(gè) 72 ans = min(ans, mid); 73 } 74 else l = mid + 1; // 當(dāng)前速度不符合要求的話,就必須加大速度 75 } 76 printf("%d\n", ans); 77 } 78 79 return 0; 80 }?
轉(zhuǎn)載于:https://www.cnblogs.com/miaowTracy/p/4853612.html
總結(jié)
以上是生活随笔為你收集整理的LA 4254 Processor 处理器 【二分 贪心 优先队列】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 新手学逆向,调试abexcm1过程
- 下一篇: OC-NSString从文件中读取字符串