UVALive 7147 World Cup(貪心+分類討論)

大佬的講解: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;
}


發佈了381 篇原創文章 · 獲贊 119 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章