UVALive - 7147 World Cup 贪心(思路题)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiang_6/article/details/81670503

题意:

给定n个人,选m个人晋级,只有胜负平三种关系,分别得分A,B,C,大小关系不限定

思路:

这个题真的考验思路,首先我们要从正常的比赛观念中跳出来,贪心的进行处理

首先假设他们按照最后的得分大小排好了顺序,那么我们要求的最大不晋级分数ans1和最小晋级分数ans2

就分别是第 m+1 个人和第 m 个人的分数,

因为胜负是同时产生和消亡的,就像黑洞周围产生的阴阳粒子,所以我们交换A和C的值,保证A>C;B不能改变;

对于ans1:要让第m+1个人的分数尽量大,那就把前m+1个人看做一个整体,在保证这个整体分数最大的同时,让这个整体中的每个队分数尽量平均;

那么他们每个人跟后面的 n-m-1 个人比赛时,无论胜负平,都要选择分数大的那个,(n-m-1)*max(A,B) ; 然后剩下的m场比赛在他们之间进行,为了保证分数尽量平均,他们的胜负数量应该是相同的或者全是平局((m/2)*max(A+C,2*B)),但是m是奇数时,就会导致胜负不平衡,这时候要考虑有一场比赛一半人胜一半人负或者全是平局 (max(C,B))  // 这段话的三个式子都是第m+1个人的得分;

对于ans2,同理;

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <set>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;

ll n, m;
ll A, B, C;

int main() {
  int T; scanf("%d", &T);
  int kase = 1;
  while(T--) {
    scanf("%lld%lld", &n, &m);
    scanf("%lld%lld%lld", &A, &B, &C);
    if(A < C) swap(A,C);
    ll ans1 = 0, ans2 = 0;
    ans1 = (n-m-1)*max(A,B) + (m/2)*max(A+C,2*B);
    if(m&1) ans1 += max(B,C);
    ans2 = (m-1)*min(B,C) + ((n-m)/2)*min(A+C,2*B);
    if((n-m)&1) ans2 += min(A,B);

    printf("Case #%d: %lld %lld\n", kase++, ans1, ans2);
  }

  return 0;
}

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/81670503