[CF 976E][思维题] Well played!

题目描述:
题目链接:
Educational Codeforces Round 43 (Rated for Div. 2) E 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 hp i and its damage dmg i. Max also has two types of spells in stock:
1.Doubles health of the creature ( h p i hp_i hpi := h p i hp_i hpi·2);
2.Assigns value of health of the creature to its damage ( d m g i dmg_i dmgi := h p i hp_i 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.
题目大意:
有n个生物,每个生物都具有健康值 h p i hp_i hpi和攻击值 d m g i dmg_i dmgi。现在有两种魔法分别最多能施展a次和b次。第一种魔法可以选择将一个生物的健康值 h p i hp_i hpi乘2,第二种魔法可将该生物健康值 h p i hp_i hpi的值赋给攻击值 d m g i dmg_i dmgi。求最后所有生物攻击值总和的最大值是多少?
输入格式:
输入第一行,包括整数n,a和b(1 ≤ n ≤ 2· 1 0 5 10^5 105, 0 ≤ a ≤ 20, 0 ≤ b ≤ 2· 1 0 5 10^5 105)
接下来n行,第i行为第i个生物的 h p i hp_i hpi d m g i dmg_i dmgi
输出格式:
输出仅一行,即所求最大值。
样例输入输出:
input

2 1 1
10 15
6 1

output

27

input

3 0 3
10 8 7
11 5 2

output

26

题目分析:
逐步分析:
如果a、b均为0,那么答案就是 d m g i dmg_i dmgi的和。
如果a为0,b不为0。那么就可以选b个生物进行转化,很明显肯定是需要选转化后值增大最大的,即选 h p i hp_i hpi- d m g i dmg_i dmgi最大的b个,这样总的收益才是最大的。 h p i hp_i hpi- d m g i dmg_i dmgi大于0,的可能不足b个,所以第二种魔法次数不一定要使用完。
如果a、b均不为0,很明显第一种魔法全部施加在同一生物上才是最优的(如果你将a次分给两个生物,那么你将a次全分给这两个生物之一,一定更优,因为翻倍的增长是很快的),而且还得对这个生物施加第二种魔法(你不转化,第一种魔法施不施加都没有意义)。所以可以先施行b-1次第二种魔法,给第一种魔法留一次,然后直接暴力枚举每一个生物就可以了,取总和最大的为答案。
附代码:

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

int n,a,b;
long long sum,ans;
struct node{
	long long h;
	long long d;
}A[200100];


bool comp(const node &a,const node &b)
{
	return a.h-a.d>b.h-b.d;
}

int main()
{
	//freopen("lx.in","r",stdin);
	
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&A[i].h,&A[i].d);
	sort(A+1,A+n+1,comp);
	for(int i=1;i<=b;i++) sum+=max(A[i].h,A[i].d);
	for(int i=b+1;i<=n;i++) sum+=A[i].d;
	ans=sum;
	if(b!=0)
	{
		for(int i=1;i<=b;i++) ans=max(ans,sum-max(A[i].h,A[i].d)+(A[i].h<<a));
		if(A[b].h>A[b].d) sum=sum-(A[b].h-A[b].d);
		for(int i=b+1;i<=n;i++) ans=max(ans,sum-A[i].d+(A[i].h<<a));
	}
	printf("%lld",ans);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值