此题大意:有n个随从,每个人又攻击力和生命值,现在你手里有a张神圣之灵,b张心灵之火,求最后能多少血斩杀。这样是不是暴露了什么?
好了,不开玩笑,抄一个网上大佬的题目描述:
有n个物品,能进行一类操作a次和二类操作b次,每个物品有一个权x和权y,一类操作为把某个物品的x变为原来的两倍,二类操作为令某个物品的y = x,问这n个物品的y的总和最大是多少。
这样翻译是不是无趣了很多?
这道题我们可以猜测一个结论,就是如果要翻倍,我们都只翻一个人。这个应该是很明显的一个结论。因为我么翻一个人,每翻一次就以几何级数增长。所以我们只要枚举翻哪个人,然后再判断一下让另外的那些随从的damage等于health即可。
Code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll read(){
char c;ll x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
ll n,a,b,pl=0,tot,ans,all,c[200005];
struct node{
ll att,def;
}f[200005];
ll pows(ll a,ll b){
ll base=1;
while(b){
if(b&1) base=base*a;
a=a*a;b/=2;
}
return base;
}
ll cmp(ll a,ll b){return a>b;}
int main()
{
n=read();a=read();b=read();c[0]=1e18;
for(ll i=1;i<=n;i++){
f[i].def=read();f[i].att=read();tot+=f[i].att;
c[i]=f[i].def-f[i].att;
}
ans=tot;
if(b==0){printf("%I64d",ans);return 0;}
sort(c+1,c+1+n,cmp);
for(ll i=1;i<=b-1;i++) if(c[i]>0) all+=c[i],pl=i;
for(ll i=1;i<=n;i++){
ll x=all;
if(f[i].def-f[i].att>=c[pl]) x-=f[i].def-f[i].att,x+=c[pl+1]>0?c[pl+1]:0;
x+=f[i].def*pows(2,a)-f[i].att;
ans=max(ans,x+tot);
}
printf("%I64d",ans);
return 0;
}