CF976E——贪心

题目传送门

此题大意:有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;
}

猜你喜欢

转载自blog.csdn.net/stevensonson/article/details/80169437