• UVALive


    题目链接

    题意

    n只队伍,两两之间会进行比赛,赢平输都有相应得分,所有比赛结束后,前m名可以晋级。问最大的不能晋级分数为多少,以及最小的能晋级的分数。

    分析

    智商题。。。按照要求来贪心
    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/2a+m/2c,即m/2*(a+c);
    (2)第一堆m场比赛中所有队伍都平局
    即第m+1个人得分: m/2b+m/2b,即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/2a+m/2c,m/2b+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)/2a+(n-m)/2c,即(n-m)/2*(a+c);
    (2)第一堆n-m场比赛中所有队伍都平局
    即第m个人得分: (n-m)/2b+(n-m)/2b,即(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 <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdlib>
    #include<climits>
    #include<ctype.h>
    #include<set>
    #include<map>
    #define pi acos(-1.0)
    #define mem(a) memset(a,0,sizeof(a))
    #define mems(a,b) memset((a),(b),sizeof(a))
    #define ll long long
    #define ull unsigned long long
    #define ls root<<1
    #define rs root<<1|1
    #define Ls root<<1,l,mid
    #define Rs root<<1|1,mid+1,r
    #define pb push_back
    using namespace std;
    const int maxn=100000+10;
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    
    int main()
    {
        //freopen("data","r",stdin);
        int t,cas=1;
        ll n,m,win,ping,lose;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%lld",&n,&m);
            scanf("%lld%lld%lld",&win,&ping,&lose);
            
            if(lose > win) swap(win,lose);
            
            ll big=max(win,ping);
            ll small=min(lose,ping);
            ll top,below;
            
            top=big*(n-m-1)+max(m/2*ping+m/2*ping,m/2LL*win+m/2LL*lose);
            if(m%2LL==1LL)
                top+=max(ping,lose);
            
            below=small*(m-1)+min((n-m)/2*min(win,ping)+(n-m)/2*min(win,ping),(n-m)/2LL*win+(n-m)/2LL*lose);
            if((n-m)%2LL==1LL)
                below+=min(ping,win);
            
            printf("Case #%d: %lld %lld
    ",cas++,top,below);
        }
        return 0;
    }
  • 相关阅读:
    hdu 1272 小希的迷宫
    hdu 1318 Palindromes
    ANR traces中内存占用情况解读
    请教会linux shell脚本的=~是什么意思?
    kernel struct definition location
    SecureCRT sysrq键设置
    sysrq
    Linux中断管理 (1)Linux中断管理机制【转】
    Linux suspend 流程介绍(2)之 freeze task
    Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)
  • 原文地址:https://www.cnblogs.com/fht-litost/p/7346749.html
Copyright © 2020-2023  润新知