码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces - 102222H - Fight Against Monsters - 贪心

时间:2019-06-17 01:00:21      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:putc   getch   read   优先   stdout   uri   space   get   递增   

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 - 贪心

标签:putc   getch   read   优先   stdout   uri   space   get   递增   

原文地址:https://www.cnblogs.com/Yinku/p/11037486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!