Codeforces - 102222H - Fight Against Monsters - 贪心

Posted yinku

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces - 102222H - Fight Against Monsters - 贪心相关的知识,希望对你有一定的参考价值。

https://codeforc.es/gym/102222/problem/H
题意:有一堆怪兽,怪兽有HP和ATK。你有一个英雄,英雄每次先被所有怪兽打,然后打其中一个怪兽。打的伤害递增,第一次1,第二次2,以此类推。
为什么感觉是贪心呢?证明一波。

首先开始打一个怪兽肯定一直打到死为止。那么打死他要求的次数可以二分出来(其实暴力也可以)。两只怪兽交换打的顺序会不会变好?

先打第一只怪兽:
\(num_1*sumatk+num_2*(sumatk-atk_1)\)

先打第二只怪兽:
\(num_2*sumatk+num_1*(sumatk-atk_2)\)

那么什么情况下先打第二只会更好呢?当然是上式大于下式:
\(num_1*sumatk+num_2*(sumatk-atk_1)>num_2*sumatk+num_1*(sumatk-atk_2)\)

化简:
\(num_1*atk_2>num_2*atk_1\)

当上式成立时需要交换。

插进优先队列里面一搞,又不会爆longlong。一波搞定。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

inline int read() 
    int x=0;
    int f=0;
    char c;
    do 
        c=getchar();
        if(c=='-')
            f=1;
     while(c<'0'||c>'9');
    do 
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
     while(c>='0'&&c<='9');
    return f?-x:x;


inline void _write(int x) 
    if(x>9)
        _write(x/10);
    putchar(x%10+'0');


inline void write(int x) 
    if(x<0) 
        putchar('-');
        x=-x;
    
    _write(x);
    putchar('\n');


void TestCase(int ti);

int main() 
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
    //freopen("Yinku.out","w",stdout);
#endif // Yinku
    int T=read();
    for(int ti=1;ti<=T;ti++)
        TestCase(ti);


/*---  ---*/

inline int s1(int x)
    return ((x+1)*x)>>1;


struct Monster
    int hp;
    int atk;
    int num;
    inline void calc()
        int l=1,r=1000,m;
        while(1)
            m=l+r>>1;
            if(m==l)
                int s=s1(l);
                if(s>=hp)
                    num=l;
                    return;
                
                else
                    num=r;
                    return;
                
            
            int s=s1(m);
            if(s==hp)
                num=m;
                return;
            
            else if(s<hp)
                l=m+1;
            else
                r=m;
        
    

    inline bool operator<(const Monster &m)const
        return !(atk*m.num>=m.atk*num);
    
monster;

priority_queue<Monster> pq;

void TestCase(int ti) 
    ll sumatk=0;
    int n=read();
    for(int i=1;i<=n;i++)
        monster.hp=read();
        monster.atk=read();
        sumatk+=monster.atk;
        monster.calc();
        pq.push(monster);
    
    ll sumdamage=0;
    while(!pq.empty())
        monster=pq.top();
        pq.pop();
        sumdamage+=sumatk*monster.num;
        sumatk-=monster.atk;
    
    printf("Case #%d: %lld\n",ti,sumdamage);

以上是关于Codeforces - 102222H - Fight Against Monsters - 贪心的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #587 (Div. 3) F Wi-Fi(线段树+dp)

CodeForces - 393E Yet Another Number Sequence

CodeForces - 939ALove Triangle

CodeForces - 392C Yet Another Number Sequence (二项式展开+矩阵加速)

codeforces840E In a Trap

模板斜率优化dp