杭電ACM 4864,Task(貪心)

2021-09-11 19:44:02 字數 1501 閱讀 9534

題意:有n個機器和m個任務,每個機器每天都有乙個最大工作時長x1,以及最大工作難度y1,每個任務都有乙個工作時間x2,工作難度y2。每完成乙個任務多有乙個收益500×x2+2×y2。假設每個機器一天只能完成乙個任務,乙個任務只能又乙個機器完成,不可由多個一起完成。求一天當中能完成的最多工,並輸出收益。若有多種情況,輸出最大的收益。

限制條件:1<=n,m<=100000;1<=x1,x2<=1440;1<=y1,y2<=100。

分析:這道題的難點在於,對於每個機器都有兩個指標去影響它的任務分配,即時間x1>=x2?和難度y1>=y2?一開始想找個權值,能夠同時衡量兩個指標,但很遺憾沒能找到,或者根本不存在,於是在網上看了牛人的思路,覺得十分巧妙,應向牛人學習。

貪心策略:能夠完成任務的條件是x1>=x2,y1>=y2,因此,對於每個任務,我們要優先選出那個可接受的工作時間,工作難度都比它大,而且可接受的工作難度最接近它的機器

先設定乙個結構體node,包含時間t,難度l兩個成員,開闢mach,task兩個陣列,兩個陣列都按t從大到小排,t同則按l從大到小排序,同時,開闢輔助陣列level[101](關鍵),level的下標表示工作的難度,是有意義的,陣列元素初始化為0

第一步:設i,j分別為任務,機器的下標,對於第i個任務,我們找出所有mach[j],t>=task[i].t的機器,記錄下滿足此條件的機器的工作難度的個數,也就是說level[mach[j].l]++;當mach[j].t偽**如下(主要寫第一步和第二步的實現):

for(i=0,j=0;i<=m-1;i++) //i,j分別表示任務和機器的下標。

for(k=task[i].l;k<=100;k++)

}**如下:

#include#include#includeusing namespace std;

struct node

task[100005],mach[100005];

int level[101];

bool cmp(node x,node y)

int main()

for(k=task[i].l;k<=100;k++)

}} printf("%lld %lld\n",cnt,ans);

} return 0;

}

小結:

1.此題十分巧妙之處就是,引入了乙個輔助陣列level,並賦予了level下標具體的意義,這是很抽象但又很巧秒的做法(跟dp有點類似)。

2.此題的貪心策略比較的複雜,首先先考慮時間,其次考慮難度,而且,對於難度這項指標,要選擇比任務大且最接近它的,這樣做的原因是為了讓後面的任務更加有可能被分配上。但對於時間是沒有必要這樣的。兩句話概括,時間確定後,難度就成了關鍵

3.此題另外乙個有收穫的地方就是,結構體的運用,bool cmp函式的運用,以及它們與sort函式的運用,具有很大的參考意義。

杭電ACM 建房子(貪心)

突破口 充分利用每一堵牆,有牆出現,其所在的行 列都加權1 除非遇到另一堵牆才停止 依次從權值由高到低開始建,每建一座,其所在的行 列都設定為n no 除非遇到牆才停止 如下 include include includeusing namespace std char map 6 6 製作一張圖 ...

hdu 4864 Task 貪心 技巧

題目鏈結 一道很有技巧的貪心題目。題意 有n個機器,m個任務。每個機器至多能完成乙個任務。對於每個機器,有乙個最大執行時間xi和等級yi,對於每個任務,也有乙個執行時間xj和等級yj。只有當xi xj且yi yj的時候,機器i才能完成任務j,並獲得 500 xj 2 yj金錢。問最多能完成幾個任務,...

HDU 4864 Task(2014多校 貪心)

task 比賽當時思路想的差不多,感覺能過的,該處理的也都處理到了,最後還是沒過,可能是二分寫錯了吧 大意 給你n個機器,m個要完成的任務,每個機器跟任務都有兩個屬性,機器是最大工作時間跟等級,任務是需要工作的時間跟等級。完成乙個任務可以得到500 工作時間 2 等級 的報酬。完成任務的條件是機器的...