大佬的講解:http://www.cnblogs.com/qq2424260747/p/4905426.html
題目大意:n個隊伍參加比賽,有m個隊伍晉級,n個隊伍有n-1場比賽,每兩個隊伍之間都有一場比賽。一場比賽贏的得a分,輸的得c分,平局得b分,問沒有晉級的隊伍最高分和晉級的隊伍最低分
分析:
1.沒有晉級的隊伍最高分
將隊伍分爲兩堆,分別爲m+1,n-m-1;令第m+1個隊伍就是沒晉級分數最高的隊伍
第m+1個人與第二堆裏面的隊伍的n-m-1場比賽中得分要麼每場都贏,要麼每場都平局
即第m+1個人的得分: (n-m-1)*max(a, b);
貪心的讓第一堆的分數高,要使第m+1個隊伍就是沒晉級分數最高的隊伍,有兩種可能
(1)第一堆m場比賽中所有隊伍中每個隊伍贏得場數和輸的場數基本相同
即第m+1個人得分 : m/2*a+m/2*c,即m/2*(a+c);
(2)第一堆m場比賽中所有隊伍都平局
即第m+1個人得分: m/2*b+m/2*b,即m/2*(b+b);
與第一堆的比賽得分取以上兩場比賽的最大值
即:max(m/2*(a+c),m/2*(b+b));
第一堆的m場比賽有可能是奇數場也有可能是偶數場,如果是奇數場那麼第m+1個人的得分還得加上最後一場的得分,第一堆的最後一場比賽有可能輸也有可能平局(不能贏,如果贏了那這個隊就有可能比前m-1個隊伍分高,就應該晉級),所以得分爲max(b, c);
最終第m+1個人的得分爲:
x = (n-m-1)*max(a, b)+max(m/2*a+m/2*c,m/2*b+m/2*b)
如果m爲奇數x+= max(b, c);否則爲x;
2.晉級的隊伍最低分
將隊伍分爲兩堆,分別爲m-1,n-m+1;令第m個隊伍就是晉級分數最低的隊伍
第m個人與第一堆裏面的隊伍的m-1場比賽中得分要麼每場都輸,要麼每場都平局
即第m個人的得分: (m-1)*min(c, b);
貪心的讓第二堆的分數低,要使第m個隊伍就是晉級分數最低的隊伍,有兩種可能
(1)第二堆n-m場比賽中所有隊伍中每個隊伍贏得場數和輸的場數基本相同
即第m個人得分 : (n-m)/2*a+(n-m)/2*c,即(n-m)/2*(a+c);
(2)第一堆n-m場比賽中所有隊伍都平局
即第m個人得分: (n-m)/2*b+(n-m)/2*b,即(n-m)/2*(b+b);
與第一堆的比賽得分取以上兩場比賽的最小值
即:min((n-m)/2*(a+c),(n-m)/2*(b+b));
第二堆的n-m場比賽有可能是奇數場也有可能是偶數場,如果是奇數場那麼第m個人的得分還得加上最後一場的得分,第一堆的最後一場比賽有可能贏也有可能平局(不能輸,如果輸的話,那該隊得的分數就比第二堆其他隊的分數低就不能晉級了),所以得分爲min(b, a);
最終第m個人的得分爲:
x = (m-1)*min(c, b)+min((n-m)/2*(a+c),(n-m)/2*(b+b))
如果n-m爲奇數x+= min(b, a);否則爲x;
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int main()
{
int kase=0, T;
scanf("%d", &T);
LL n, m, a, b, c, x, y;
while(T--)
{
x=y=0;
scanf("%lld%lld", &n, &m);
scanf("%lld%lld%lld", &a, &b, &c);
if(a<c) swap(a, c);
x+=(n-m-1)*max(a, b);
x+=max(m/2*(a+c), m/2*(b+b));
if(m%2!=0) x+=max(b, c);
y+=(m-1)*min(b, c);
y+=min((n-m)/2*(a+c), (n-m)/2*(b+b));
if((n-m)%2!=0) y+=min(a, b);
printf("Case #%d: %lld %lld\n", ++kase, x, y);
}
return 0;
}