Codeforces 488C Fight the Monster【二分+枚举】

主人公与怪物战斗,通过购买属性提升战斗力,目标是最小化花费确保胜利。文章介绍了一个算法,利用二分查找和枚举策略确定最低成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Fight the Monster
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

A monster is attacking the Cyberland!

Master Yang, a braver, is going to beat the monster. Yang and the monster each have 3 attributes: hitpoints (HP), offensive power (ATK) and defensive power (DEF).

During the battle, every second the monster's HP decrease by max(0, ATKY - DEFM), while Yang's HP decreases by max(0, ATKM - DEFY), where index Y denotes Master Yang and index M denotes monster. Both decreases happen simultaneously Once monster's HP ≤ 0 and the same time Master Yang's HP > 0, Master Yang wins.

Master Yang can buy attributes from the magic shop of Cyberland: h bitcoins per HP, a bitcoins per ATK, and d bitcoins per DEF.

Now Master Yang wants to know the minimum number of bitcoins he can spend in order to win.

Input

The first line contains three integers HPY, ATKY, DEFY, separated by a space, denoting the initial HP, ATK and DEF of Master Yang.

The second line contains three integers HPM, ATKM, DEFM, separated by a space, denoting the HP, ATK and DEF of the monster.

The third line contains three integers h, a, d, separated by a space, denoting the price of HP, ATK and DEF.

All numbers in input are integer and lie between 1 and 100 inclusively.

Output

The only output line should contain an integer, denoting the minimum bitcoins Master Yang should spend in order to win.

Examples
Input
1 2 1
1 100 1
1 100 100
Output
99
Input
100 100 100
1 1 1
1 1 1
Output
0
Note

For the first sample, prices for ATK and DEF are extremely high. Master Yang can buy 99 HP, then he can beat the monster with 1 HP left.

For the second sample, Master Yang is strong enough to beat the monster, so he doesn't need to buy anything.


题目大意:

告诉你了主人公的血量,攻击力,防御值。
同时告诉你了敌人的血量,攻击力,防御值。
那么攻击一下敌人造成的伤害为攻击力-敌人的防御力
一个人的血量值低于
再告诉你了加一点血量的花费,加一点攻击力的花费,加一点防御值的花费。
问最少花费,使得主人公能够打败敌人。

思路:

1、明显有这样的递增性质:如果我们花费的钱越多,那么造成的伤害(胜利的机会)就越大。
那么我们二分花费 。

2、对应二分出来的当前花费值mid,我们通过枚举可行解来判断:
①攻击力达到200+(因为敌人的防御力最高100,并且生命值最高200,我们极限枚举,一下就打死敌人的情况)
②防御力达到100+(因为敌人的攻击力最高100,这时候敌人就打不动我们了)
③生命值达到1000+(因为敌人的攻击力最高100,假设我们这个时候防御力为1,每秒能对敌人造成1点伤害,那么我们要抗住100*100回合才行)
全部考虑出极限值,然后进行枚举即可,判断当前二分值是否可行,同时记录可行解,一直二分下去即可。

Ac代码:

#include<stdio.h>
#include<string.h>
using namespace std;
#define ll __int64
ll a,b,c;
ll d,e,f;
ll pa,pb,pc;
int Slove(ll money)
{
    for(ll i=0;i<=10250;i++)
    {
        if(pa*i>money)break;
        for(ll j=0;j<=220;j++)
        {
            if(pa*i+pb*j>money)break;
            for(ll k=0;k<=120;k++)
            {
                ll cost=pa*i+pb*j+pc*k;
                if(cost>money)break;
                ll tmpa=a+i;
                ll tmpb=b+j;
                ll tmpc=c+k;
                ll damage=tmpb-f;
                if(damage<=0)break;
                ll damage2=e-tmpc;
                if(damage2<=0)
                {
                    return 1;
                }
                ll win=d/damage;
                if(d%damage!=0)win++;
                ll win2=tmpa/damage2;
                if(tmpa%damage2!=0)win2++;
                if(win<win2)
                {
                    return 1;
                }
            }
        }
    }
    return 0;
}
int main()
{
    while(~scanf("%I64d%I64d%I64d",&a,&b,&c))
    {
        scanf("%I64d%I64d%I64d",&d,&e,&f);
        scanf("%I64d%I64d%I64d",&pa,&pb,&pc);
        ll l=0;ll r=10000000000;
        ll ans=-1;
        while(r>=l)
        {
            ll mid=(l+r)/2;
            if(Slove(mid)==1)
            {
                r=mid-1;
                ans=mid;
            }
            else l=mid+1;
        }
        printf("%I64d\n",ans);
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值