UVa Live 7147 貪心(2014 上海區域賽)
阿新 • • 發佈:2019-01-29
這個題已經過了一年了。。。本來當時就想寫題解但是沒找到題。。最近有人問我才知道原來UVa Live有歷年題目。。。
去年在現場的時候這題也是卡了好久。。。重寫了兩三次。。封榜了才過。。
題意:有n只隊伍,每隻隊伍要和其他n-1只隊伍比賽,每場比賽獲勝得a分,平局得b分,敗北得c分,共有m只隊伍可以晉級,問最高淘汰分和最低晉級分分別是多少。
思路:這個題的細節真的很多。。
首先如果獲勝分<敗北分,互換兩個分數。
然後考慮分數儘量平均的分配方式:
在偶數個人中,想讓所有人分數相等有兩種方式,所有人平局或贏一半的人輸一半的人;
在奇數個人中,要麼所有人平局,要麼一部分人多輸一局。
最高淘汰分:第m+1人,對於其後面的n-m-1人都應該選擇贏或者平局,對於前面的m人,按照上面的分數分配方式選擇分較高的一種。
最低晉級分:第m人,對於其前面的m-1人都應該選擇輸或平局,對於後面的n-m人,按照上面的分數分配方式選擇分較少的一種。
這道題的細節很多,有一個需要注意的地方是對於奇數個人m,不應該比較m/2 * (win + lose)和 m * draw,這樣draw會多算一個,我就在這個地方卡了很久。。。(好像當時比賽的時候也在這裡卡了很久。。)
#include <iostream> #include <algorithm> using namespace std; main() { long long n, m, win, draw, lose; int t, cas = 1; cin >> t; while(t--){ cin >> n >> m >> win >> draw >> lose; if(win < lose) swap(win, lose); long long pass = 0, out = 0; if(m % 2 == 0){ if(draw < lose) pass = draw * (n - 1);//如果平局分數最低 那麼最低晉級分就是所有人平局 else { pass = (m - 1) * lose;//和前面的m-1人比一定是輸的 long long p = n - m; pass += (p / 2) > 0 ? min(win + lose, draw + draw) * (p / 2) : 0;//和後面的人比,看哪種分數相同的情況分數最低 if(p % 2) pass += min(draw, win);//如果是奇數情況,那麼要麼贏最後一名,要麼所有人平局,反正總分要低 } if(draw > win) out = draw * (n - 1);//如果平局分數最低 那麼最高淘汰分就是所有人平局 else{ out = (m / 2) > 0? max(win + lose, draw + draw) * (m / 2) : 0;//和前面的人比,看哪種分數分數相同的情況分數最高 out += (n - m - 1) * win;//和後面的人比一定是贏的 } } else { if(draw < lose) pass = draw * (n - 1); else{ pass = (m - 1) * lose; long long p = n - m; pass += (p / 2) > 0 ? min(win + lose, draw + draw) * (p / 2) : 0; if(p % 2) pass += min(win, draw); } if(draw > win) out = draw * (n - 1); else { out = (m / 2) > 0? max(win + lose, draw + draw) * (m / 2) : 0; out += max(draw, lose) + (n - m - 1) * win;//和前面的人比 如果是奇數情況 要麼平要麼輸 選分高的一種 } } cout << "Case #" << cas++ << ": " << out << " " << pass << endl; } }