Title

CF976E Well played! 题解

解题思路

两个显然的结论:

  • 将所有生物 hpidmgi 的值按照从大到小的顺序排序后,将正值部分全部进行 b 操作(如果可以的话),这样是最优的;
  • 将所有的 a 操作全部在同一生物上进行是最优的,证明如下(假设只有两个,多个同样成立):
    • f(i,x)=hpi×2x,则 f(j,y)=hpj×2y,由此可得分开的值 sum=f(i,x)+f(j,y)dmgidmgj,在一个生物上进行的值为 f(i,x+y)+f(j,0)dmgidmgj,不妨设 hpi>hpj
    • 假设 f(i,x+y)+f(j,0)dmgidmgj<sum,则 f(i,x+y)+f(j,0)<f(i,x)+f(j,y),移项可得 f(i,x+y)f(i,x)<f(j,y)f(j,0),带入得到 hpi×(2y1)×2x<hpj×(2y1),不等式两边同时除以 2y1 可得 hpi×2x<hpj ,又因为 hpi>hpj,故等式不成立,f(i,x+y)+f(j,0)dmgidmgjsum
    • 综上,将 a 全部赋为一个生物最优。

接下来只需要简单的贪心就可以了,但是有些细节需要注意一下。

AC 代码

#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
#define N 200005
#define int ll
int n,a,b,d[N];
struct QWQ{int hp;int dmg;}s[N];
inline bool cmp(QWQ A,QWQ B){
    if(A.hp-A.dmg==B.hp-B.dmg)
        return A.hp>B.hp;
    return A.hp-A.dmg>B.hp-B.dmg;
}
signed main(){
    scanf("%lld%lld%lld",&n,&a,&b);
    for(register int i=1;i<=n;++i){
        scanf("%lld",&s[i].hp),
        scanf("%lld",&s[i].dmg);
    }std::sort(s+1,s+n+1,cmp);
    int replace=0,maxt1=-1,res=0;
    for(register int i=1;i<=n;++i)
        res+=s[i].dmg,d[i]=s[i].dmg;
    if(b==0){printf("%lld",res);return 0;}
    if(b){for(register int i=1;i<=n;++i){
            int sub=s[i].dmg;
            int now=(1ll<<a)*s[i].hp-sub;
            maxt1=std::max(maxt1,now);
        }res=res+maxt1;
    }for(register int i=1;i<=n;++i){
        if(s[i].hp<=s[i].dmg||!b) break;
        s[i].dmg=s[i].hp;--b;++replace;
    }int ans=0;
    for(register int i=1;i<=n;++i)
        ans+=s[i].dmg;
    int Maxt=-1,Mint=s[replace].dmg,Mini=replace;
    for(register int i=1;i<=replace;++i){
        if(s[i].hp>Maxt) Maxt=s[i].hp;
    }int maxt=((1ll<<a)-1)*Maxt;
    if(b>0){for(register int i=replace+1;i<=n;++i){
            int sub=s[i].dmg;
            int now=(1ll<<a)*s[i].hp-sub;
            maxt=std::max(maxt,now);
        }
    }else{for(register int i=replace+1;i<=n;++i){
            int sub=s[i].dmg;
            int now=(1ll<<a)*s[i].hp-sub;
            maxt=std::max(maxt,now-Mint+d[Mini]);
        }
    }printf("%lld",maxt+ans>res?maxt+ans:res);
}
posted @   UncleSam_Died  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示