[CF976E]Well played!

时间:2023-03-09 16:57:37
[CF976E]Well played!

题目描述

Recently Max has got himself into popular CCG "BrainStone". As "BrainStone" is a pretty intellectual game, Max has to solve numerous hard problems during the gameplay. Here is one of them:
Max owns n creatures, i-th of them can be described with two numbers — its health hpi and its damage dmgi. Max also has two types of spells in stock:
Doubles health of the creature (hpi := hpi·2);
Assigns value of health of the creature to its damage (dmgi := hpi).
Spell of first type can be used no more than a times in total, of the second type — no more than b times in total. Spell can be used on a certain creature multiple times. Spells can be used in arbitrary order. It isn't necessary to use all the spells.
Max is really busy preparing for his final exams, so he asks you to determine what is the maximal total damage of all creatures he can achieve if he uses spells in most optimal way.

题目大意

给你两种操作,一个操作是让hp变成原来的两倍,另一个是让dmg值变成hp值,求最大的dmg的值和。

100分解法

其实比较好想,因为每次hp变大,必然会使和对应的dmg值的差距变小或者比dmg大的更多,我们就大胆的假设把\(a\)全用在一个人身上时,这个答案最优。
那么关于\(b\)的操作,就一定是hp比dmg大的多的要用\(b\),这样我们的贪心策略就好了。

100分代码

#include<bits/stdc++.h>
#define LL long long
#define N 200005
using namespace std;
struct node{LL hp,d;}fi[N];
int n,a,b;
LL ans;
LL r(){LL x=0,w=0;char ch=0;while(!isdigit(ch))w|=ch=='-',ch=getchar();while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();return w?-x:x;}
bool cmp(node a,node b){return a.hp-a.d>b.hp-b.d;}//按照差值排序
int main(){
    n=r(),a=r(),b=r();
    for(int i=1;i<=n;i++)fi[i]=(node){r(),r()};
    sort(fi+1,fi+1+n,cmp);
    for(int i=1;i<=b;i++)ans+=max(fi[i].d,fi[i].hp);
    for(int i=b+1;i<=n;i++)ans+=fi[i].d; //先算出处理b的答案
    LL sum=ans;
    for(int i=1;i<=b;i++)ans=max(ans,sum-max(fi[i].d,fi[i].hp)+(fi[i].hp<<a));//开始处理a的答案
    sum=sum-max(fi[b].d,fi[b].hp)+fi[b].d;
    for(int i=b+1;i<=n&&b;i++)ans=max(ans,sum-fi[i].d+(fi[i].hp<<a));
    printf("%I64d\n",ans);
    return 0;
}