zoukankan      html  css  js  c++  java
  • Codeforces

    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('
    ');
    }
    
    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
    ",ti,sumdamage);
    }
    
  • 相关阅读:
    [Java] JDBC 06 批Transaction处理 -- conn.setAutoCommit(false); // 不让其自动提交 (很重要的知识点)
    [Java] JDBC 05 TestBatch.java 批处理 Batch
    [Java] JDBC 04 TestProc.java (对存储过程进行调用 CallableStatement)
    [Java] JDBC 03 TestPrepStmt.java
    美化复选框
    美化单选框
    canvas
    html5新增标签
    旋转、水平翻转、垂直翻转
    dede让channelartlist标签支持currentstyle属性 完美解决
  • 原文地址:https://www.cnblogs.com/Yinku/p/11037486.html
Copyright © 2011-2022 走看看