前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Codeforces 976E 题解报告

Codeforces 976E 题解报告

作者头像
海天一树
发布2018-07-25 12:27:28
2940
发布2018-07-25 12:27:28
举报
文章被收录于专栏:海天一树海天一树

一、题目

http://codeforces.com/contest/976/problem/E

二、分析

(1)当把所有的倍数2 ^ a都加到同一health上,health增加的最多 (2)先计算每一个creature的hp - dmg,按该值对所有的creature排序 再求和,i=b时只能取dmg。这个和里包含了第2种魔法操作,但没包含第一种魔法操作。 然后进行第一种魔法操作,对于每个creature,逐个使用用hp * 2 ^ a来替换dmg,注意i < b时,直接替换即可,i >= b时,要将前b个creature中hp - dmg最小的那个(因为排过序,第b - 1个creature的hp - dmg最小)机会腾出来,这样后面的creature才能把乘以2 ^ a后的hp赋值给dmg。 具体请看程序和注释。

三、程序

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
const int N = 200 * 1000 + 9;
int hp[N], dmg[N];
// 按生命值和破坏值的差排序,差大的排在前
// 若差相等,按原先的顺序即从小到大
bool cmp(int i, int j)
{
    if(hp[i] - dmg[i] != hp[j] - dmg[j])
    {
        return hp[i] - dmg[i] > hp[j] - dmg[j];
    }
    return i < j;
}
// 得到生命值和破坏值中的较大者
int getMaxDesc(int id)
{
    return  hp[id] > dmg[id] ? hp[id] : dmg[id];
}
int main()
{
    int n, a, b;
    scanf("%d %d %d", &n, &a, &b);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d %d", hp + i, dmg + i);
    }
    b = min(b, n);
    vector <int> creature(n);
    for(int i = 0; i < n; ++i)
    {
        creature[i] = i;
    }
    // 按creature的生命值和破坏值的差进行排序
    sort(creature.begin(), creature.end(), cmp);
    long long res = 0, sum = 0;
    for(int i = 0; i < n; ++i)
    {
        int id = creature[i];
        /*
         * 初始不考虑a
         * i<b,可以把生命值赋值给破坏值
         * i>=b,不能把生命值赋值给破坏值
         */
        if(i < b)
        {
            sum += getMaxDesc(id);
        }
        else
        {
            sum += dmg[id];
        }
    }
    res = sum;
    if(b == 0)
    {
        printf("%I64d\n", res);
        return 0;
    }
    // 所有的a加给同一creature时翻倍最多,倍数为2的a次幂
    long long mutiple = (1LL << a);
    for(int i = 0; i < n; ++i)
    {
        int id = creature[i];
        long long newsum = sum;
        if(i < b)
        {
            // 挨个用翻倍后的生命值来替换,看看哪个最大
            newsum -= getMaxDesc(id);
            newsum += hp[id] * mutiple;
            res = max(res, newsum);
        }
        else
        {
            // 因为排过序,在0~b-1步中,第b-1步获得的破坏值是最小的
            // 先让第b-1步不用生命值替换,直接取破坏值
            // 这样就获得了一次替换的机会
            int id2 = creature[b - 1];
            newsum -= getMaxDesc(id2);
            newsum += dmg[id2];
            // 利用上一步得来的替换机会,用翻倍后的生命值替换破坏值,看看哪个最大
            newsum -= dmg[id];
            newsum += hp[id] * mutiple;
            res = max(res, newsum);
        }
    }
    printf("%I64d\n", res);
    return 0;
}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海天一树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目
  • 二、分析
  • 三、程序
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档